Skip to content

Commit 8917d5b

Browse files
committed
43216: add http/protobuf support for Coralogix exporter
Signed-off-by: Israel Blancas <[email protected]>
1 parent f33cdbc commit 8917d5b

22 files changed

+1507
-281
lines changed

.chloggen/43216.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: 'enhancement'
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: coralogixexporter
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Add HTTP/protobuf protocol support alongside existing gRPC transport.
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [43216]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: |
19+
The exporter now supports both gRPC (default) and HTTP/protobuf protocols for sending telemetry data.
20+
HTTP transport enables proxy support and provides an alternative for environments where gRPC is restricted.
21+
Configure using the `protocol` field with values "grpc" or "http".
22+
23+
# If your change doesn't affect end users or the exported elements of any package,
24+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
25+
# Optional: The change log or logs in which this entry should be included.
26+
# e.g. '[user]' or '[user, api]'
27+
# Include 'user' if the change is relevant to end users.
28+
# Include 'api' if there is a change to a library API.
29+
# Default: '[user]'
30+
change_logs: []

exporter/coralogixexporter/README.md

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ exporters:
3434
# Your Coralogix private key is sensitive
3535
private_key: "xxx"
3636

37+
# (Optional) Protocol to use for communication: "grpc" (default) or "http"
38+
protocol: "grpc"
39+
3740
# (Optional) Ordered list of Resource attributes that are used for Coralogix
3841
# AppName and SubSystem values. The first non-empty Resource attribute is used.
3942
# Example: application_name_attributes: ["k8s.namespace.name", "service.namespace"]
@@ -43,7 +46,7 @@ exporters:
4346
subsystem_name_attributes:
4447
- "service.name"
4548

46-
# Traces, Metrics and Logs emitted by this OpenTelemetry exporter
49+
# Traces, Metrics and Logs emitted by this OpenTelemetry exporter
4750
# are tagged in Coralogix with the default application and subsystem constants.
4851
application_name: "MyBusinessEnvironment"
4952
subsystem_name: "MyBusinessSystem"
@@ -52,13 +55,38 @@ exporters:
5255
sending_queue:
5356
sizer: bytes
5457
batch:
55-
min_size: 4194304
58+
min_size: 4194304
5659
max_size: 8388608
5760

5861
# (Optional) Timeout is the timeout for every attempt to send data to the backend.
5962
timeout: 30s
6063
```
6164
65+
### Transport Protocol
66+
67+
The Coralogix exporter supports two transport protocols:
68+
- **gRPC** (default): Uses gRPC for efficient binary communication
69+
- **HTTP**: Uses HTTP with protobuf encoding, useful for proxy support or environments where gRPC is restricted
70+
71+
To use HTTP protocol:
72+
```yaml
73+
exporters:
74+
coralogix:
75+
protocol: "http"
76+
domain: "coralogix.com"
77+
```
78+
79+
When using HTTP protocol with a proxy:
80+
```yaml
81+
exporters:
82+
coralogix:
83+
protocol: "http"
84+
domain: "coralogix.com"
85+
domain_settings:
86+
proxy_url: "http://proxy.example.com:8080"
87+
timeout: 30s
88+
```
89+
6290
### Compression
6391
6492
By default, the Coralogix exporter uses gzip compression. Alternatively, you can use zstd compression, for example:
@@ -70,7 +98,7 @@ exporters:
7098
compression: "zstd"
7199
```
72100
73-
### v0.76.0 Coralogix Domain
101+
### v0.76.0 Coralogix Domain
74102
75103
Since v0.76.0 you can specify Coralogix domain in the configuration file instead of specifying different endpoints for traces, metrics and logs. For example, the configuration below, can be replaced with domain field:
76104

exporter/coralogixexporter/config.go

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44
package coralogixexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/coralogixexporter"
55

66
import (
7+
"context"
78
"errors"
89
"fmt"
10+
"net/http"
911
"strings"
1012
"time"
1113

14+
"go.opentelemetry.io/collector/component"
1215
"go.opentelemetry.io/collector/config/configgrpc"
16+
"go.opentelemetry.io/collector/config/confighttp"
1317
"go.opentelemetry.io/collector/config/configopaque"
1418
"go.opentelemetry.io/collector/config/configretry"
1519
"go.opentelemetry.io/collector/exporter/exporterhelper"
@@ -19,33 +23,67 @@ import (
1923
const (
2024
cxAppNameAttrName = "cx.application.name"
2125
cxSubsystemNameAttrName = "cx.subsystem.name"
26+
httpProtocol = "http"
27+
grpcProtocol = "grpc"
2228
)
2329

24-
// Config defines by Coralogix.
30+
// TransportConfig extends configgrpc.ClientConfig with additional HTTP-specific settings
31+
type TransportConfig struct {
32+
// Embed the gRPC configuration to ensure backward compatibility
33+
configgrpc.ClientConfig `mapstructure:",squash"`
34+
35+
// The following fields are only used when protocol is "http"
36+
ProxyURL string `mapstructure:"proxy_url,omitempty"` // Used only if protocol is http
37+
Timeout time.Duration `mapstructure:"timeout,omitempty"` // Used only if protocol is http
38+
}
39+
40+
func (c *TransportConfig) ToHTTPClient(ctx context.Context, host component.Host, settings component.TelemetrySettings) (*http.Client, error) {
41+
headers := c.Headers
42+
if headers == nil {
43+
headers = make(map[string]configopaque.String)
44+
}
45+
headers["Content-Type"] = "application/x-protobuf"
46+
47+
httpClientConfig := confighttp.ClientConfig{
48+
ProxyURL: c.ProxyURL,
49+
TLS: c.TLS,
50+
ReadBufferSize: c.ReadBufferSize,
51+
WriteBufferSize: c.WriteBufferSize,
52+
Timeout: c.Timeout,
53+
Headers: headers,
54+
Compression: c.Compression,
55+
}
56+
return httpClientConfig.ToClient(ctx, host, settings)
57+
}
58+
59+
// Config defines configuration for Coralogix exporter.
2560
type Config struct {
2661
QueueSettings exporterhelper.QueueBatchConfig `mapstructure:"sending_queue"`
2762
configretry.BackOffConfig `mapstructure:"retry_on_failure"`
2863
TimeoutSettings exporterhelper.TimeoutConfig `mapstructure:",squash"`
2964

65+
// Protocol to use for communication. Options: "grpc" (default), "http"
66+
Protocol string `mapstructure:"protocol"`
67+
3068
// Coralogix domain
3169
Domain string `mapstructure:"domain"`
3270

33-
// GRPC Settings used with Domain
34-
DomainSettings configgrpc.ClientConfig `mapstructure:"domain_settings"`
71+
// Transport settings used with Domain (supports both gRPC and HTTP)
72+
DomainSettings TransportConfig `mapstructure:"domain_settings"`
3573

3674
// Use AWS PrivateLink for the domain
3775
PrivateLink bool `mapstructure:"private_link"`
3876

39-
// Coralogix traces ingress endpoint
40-
Traces configgrpc.ClientConfig `mapstructure:"traces"`
77+
// Coralogix traces ingress endpoint (supports both gRPC and HTTP)
78+
Traces TransportConfig `mapstructure:"traces"`
4179

42-
// The Coralogix metrics ingress endpoint
43-
Metrics configgrpc.ClientConfig `mapstructure:"metrics"`
80+
// The Coralogix metrics ingress endpoint (supports both gRPC and HTTP)
81+
Metrics TransportConfig `mapstructure:"metrics"`
4482

45-
// The Coralogix logs ingress endpoint
46-
Logs configgrpc.ClientConfig `mapstructure:"logs"`
83+
// The Coralogix logs ingress endpoint (supports both gRPC and HTTP)
84+
Logs TransportConfig `mapstructure:"logs"`
4785

48-
// The Coralogix profiles ingress endpoint
86+
// The Coralogix profiles ingress endpoint (gRPC only)
4987
Profiles configgrpc.ClientConfig `mapstructure:"profiles"`
5088

5189
// Your Coralogix private key (sensitive) for authentication
@@ -146,7 +184,7 @@ func (c *Config) getMetadataFromResource(res pcommon.Resource) (appName, subsyst
146184
}
147185

148186
func (c *Config) getDomainGrpcSettings() *configgrpc.ClientConfig {
149-
settings := c.DomainSettings
187+
settings := c.DomainSettings.ClientConfig
150188
domain := c.Domain
151189

152190
// If PrivateLink is enabled, use the private link endpoint.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
receivers:
2+
otlp:
3+
protocols:
4+
grpc:
5+
endpoint: 0.0.0.0:4317
6+
http:
7+
endpoint: 0.0.0.0:4318
8+
9+
exporters:
10+
debug:
11+
coralogix:
12+
protocol: http
13+
application_name: otel
14+
application_name_attributes:
15+
- service.name
16+
- k8s.namespace.name
17+
- service.namespace
18+
domain: eu2.coralogix.com
19+
subsystem_name: k8s-saas
20+
subsystem_name_attributes:
21+
- subsystem.name
22+
private_key: ${env:CORALOGIX_PRIVATE_KEY}
23+
24+
service:
25+
pipelines:
26+
traces:
27+
receivers: [otlp]
28+
exporters: [coralogix, debug]
29+
metrics:
30+
receivers: [otlp]
31+
exporters: [coralogix, debug]
32+
logs:
33+
receivers: [otlp]
34+
exporters: [coralogix, debug]

exporter/coralogixexporter/config_test.go

Lines changed: 64 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -41,36 +41,45 @@ func TestLoadConfig(t *testing.T) {
4141
expected: &Config{
4242
QueueSettings: exporterhelper.NewDefaultQueueConfig(),
4343
BackOffConfig: configretry.NewDefaultBackOffConfig(),
44+
Protocol: "grpc",
4445
PrivateKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
4546
AppName: "APP_NAME",
4647
// Deprecated: [v0.47.0] SubSystem will remove in the next version
4748
SubSystem: "SUBSYSTEM_NAME",
4849
TimeoutSettings: exporterhelper.NewDefaultTimeoutConfig(),
49-
DomainSettings: configgrpc.ClientConfig{
50-
Compression: configcompression.TypeGzip,
50+
DomainSettings: TransportConfig{
51+
ClientConfig: configgrpc.ClientConfig{
52+
Compression: configcompression.TypeGzip,
53+
},
5154
},
52-
Metrics: configgrpc.ClientConfig{
53-
Endpoint: "https://",
54-
Compression: configcompression.TypeGzip,
55-
WriteBufferSize: 512 * 1024,
55+
Metrics: TransportConfig{
56+
ClientConfig: configgrpc.ClientConfig{
57+
Endpoint: "https://",
58+
Compression: configcompression.TypeGzip,
59+
WriteBufferSize: 512 * 1024,
60+
},
5661
},
57-
Logs: configgrpc.ClientConfig{
58-
Endpoint: "https://",
59-
Compression: configcompression.TypeGzip,
62+
Logs: TransportConfig{
63+
ClientConfig: configgrpc.ClientConfig{
64+
Endpoint: "https://",
65+
Compression: configcompression.TypeGzip,
66+
},
6067
},
61-
Traces: configgrpc.ClientConfig{
62-
Endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
63-
Compression: configcompression.TypeGzip,
64-
TLS: configtls.ClientConfig{
65-
Config: configtls.Config{},
66-
Insecure: false,
67-
InsecureSkipVerify: false,
68-
ServerName: "",
68+
Traces: TransportConfig{
69+
ClientConfig: configgrpc.ClientConfig{
70+
Endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
71+
Compression: configcompression.TypeGzip,
72+
TLS: configtls.ClientConfig{
73+
Config: configtls.Config{},
74+
Insecure: false,
75+
InsecureSkipVerify: false,
76+
ServerName: "",
77+
},
78+
ReadBufferSize: 0,
79+
WriteBufferSize: 0,
80+
WaitForReady: false,
81+
BalancerName: "",
6982
},
70-
ReadBufferSize: 0,
71-
WriteBufferSize: 0,
72-
WaitForReady: false,
73-
BalancerName: "",
7483
},
7584
RateLimiter: RateLimiterConfig{
7685
Enabled: true,
@@ -84,36 +93,45 @@ func TestLoadConfig(t *testing.T) {
8493
expected: &Config{
8594
QueueSettings: exporterhelper.NewDefaultQueueConfig(),
8695
BackOffConfig: configretry.NewDefaultBackOffConfig(),
96+
Protocol: "grpc",
8797
PrivateKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
8898
AppName: "APP_NAME",
8999
// Deprecated: [v0.47.0] SubSystem will remove in the next version
90100
SubSystem: "SUBSYSTEM_NAME",
91101
TimeoutSettings: exporterhelper.NewDefaultTimeoutConfig(),
92-
DomainSettings: configgrpc.ClientConfig{
93-
Compression: configcompression.TypeGzip,
102+
DomainSettings: TransportConfig{
103+
ClientConfig: configgrpc.ClientConfig{
104+
Compression: configcompression.TypeGzip,
105+
},
94106
},
95-
Metrics: configgrpc.ClientConfig{
96-
Endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
97-
Compression: configcompression.TypeGzip,
98-
WriteBufferSize: 512 * 1024,
107+
Metrics: TransportConfig{
108+
ClientConfig: configgrpc.ClientConfig{
109+
Endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
110+
Compression: configcompression.TypeGzip,
111+
WriteBufferSize: 512 * 1024,
112+
},
99113
},
100-
Logs: configgrpc.ClientConfig{
101-
Endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
102-
Compression: configcompression.TypeGzip,
114+
Logs: TransportConfig{
115+
ClientConfig: configgrpc.ClientConfig{
116+
Endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
117+
Compression: configcompression.TypeGzip,
118+
},
103119
},
104-
Traces: configgrpc.ClientConfig{
105-
Endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
106-
Compression: configcompression.TypeGzip,
107-
TLS: configtls.ClientConfig{
108-
Config: configtls.Config{},
109-
Insecure: false,
110-
InsecureSkipVerify: false,
111-
ServerName: "",
120+
Traces: TransportConfig{
121+
ClientConfig: configgrpc.ClientConfig{
122+
Endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
123+
Compression: configcompression.TypeGzip,
124+
TLS: configtls.ClientConfig{
125+
Config: configtls.Config{},
126+
Insecure: false,
127+
InsecureSkipVerify: false,
128+
ServerName: "",
129+
},
130+
ReadBufferSize: 0,
131+
WriteBufferSize: 0,
132+
WaitForReady: false,
133+
BalancerName: "",
112134
},
113-
ReadBufferSize: 0,
114-
WriteBufferSize: 0,
115-
WaitForReady: false,
116-
BalancerName: "",
117135
},
118136
AppNameAttributes: []string{"service.namespace", "k8s.namespace.name"},
119137
SubSystemAttributes: []string{"service.name", "k8s.deployment.name", "k8s.statefulset.name", "k8s.daemonset.name", "k8s.cronjob.name", "k8s.job.name", "k8s.container.name"},
@@ -372,8 +390,10 @@ func TestGetDomainGrpcSettings(t *testing.T) {
372390
cfg := &Config{
373391
Domain: tt.domain,
374392
PrivateLink: tt.privateLink,
375-
DomainSettings: configgrpc.ClientConfig{
376-
Compression: configcompression.TypeGzip,
393+
DomainSettings: TransportConfig{
394+
ClientConfig: configgrpc.ClientConfig{
395+
Compression: configcompression.TypeGzip,
396+
},
377397
},
378398
}
379399

0 commit comments

Comments
 (0)