Skip to content

Commit

Permalink
[exporter/sumologicexporter]: adds support for tracing (#33021)
Browse files Browse the repository at this point in the history
**Description:**

adds support for tracing

It should be the last PR which moves code from Sumo Logic repository. I
will compare the codebase after merging it

**Link to tracking Issue:**

#32315

**Testing:**

* unit tests

**Documentation:**

* Readme

---------

Signed-off-by: Dominik Rosiek <drosiek@sumologic.com>
  • Loading branch information
sumo-drosiek authored May 22, 2024
1 parent 5650e35 commit cab59ab
Show file tree
Hide file tree
Showing 14 changed files with 318 additions and 44 deletions.
27 changes: 27 additions & 0 deletions .chloggen/drosiek-tracing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: sumologicexporter

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: add support for tracing

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [32315]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:

# If your change doesn't affect end users or the exported elements of any package,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: [user]
6 changes: 4 additions & 2 deletions exporter/sumologicexporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<!-- status autogenerated section -->
| Status | |
| ------------- |-----------|
| Stability | [beta]: metrics, logs |
| Stability | [beta]: metrics, logs, traces |
| Distributions | [contrib] |
| Issues | [![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fsumologic%20&label=open&color=orange&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aopen+is%3Aissue+label%3Aexporter%2Fsumologic) [![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fsumologic%20&label=closed&color=blue&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aclosed+is%3Aissue+label%3Aexporter%2Fsumologic) |
| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@aboguszewski-sumo](https://www.github.com/aboguszewski-sumo), [@kkujawa-sumo](https://www.github.com/kkujawa-sumo), [@mat-rumian](https://www.github.com/mat-rumian), [@rnishtala-sumo](https://www.github.com/rnishtala-sumo), [@sumo-drosiek](https://www.github.com/sumo-drosiek), [@swiatekm-sumo](https://www.github.com/swiatekm-sumo) |
Expand Down Expand Up @@ -86,6 +86,8 @@ exporters:
max_request_body_size: <max_request_body_size>
# format to use when sending logs to Sumo Logic, default = otlp,
# see Sumo Logic documentation for details regarding log formats:
# https://help.sumologic.com/docs/send-data/opentelemetry-collector/data-source-configurations/mapping-records-resources/
log_format: {otlp, json, text}
# format to use when sending metrics to Sumo Logic, default = otlp,
Expand All @@ -99,7 +101,7 @@ exporters:
decompose_otlp_histograms: {true, false}

# timeout is the timeout for every attempt to send data to the backend,
# maximum connection timeout is 55s, default = 5s
# maximum connection timeout is 55s, default = 30s
timeout: <timeout>

# defines if sticky session support is enable.
Expand Down
66 changes: 42 additions & 24 deletions exporter/sumologicexporter/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ type Config struct {
// Format to post logs into Sumo. (default json)
// * text - Logs will appear in Sumo Logic in text format.
// * json - Logs will appear in Sumo Logic in json format.
// * otlp - Logs will be send in otlp format and will appear in Sumo Logic:
// * in json format if record level attributes exists
// * in text format in case of no level attributes
// See Sumo Logic documentation for more details:
// https://help.sumologic.com/docs/send-data/opentelemetry-collector/data-source-configurations/mapping-records-resources/
LogFormat LogFormatType `mapstructure:"log_format"`

// Metrics related configuration
Expand All @@ -46,6 +51,7 @@ type Config struct {
// Decompose OTLP Histograms into individual metrics, similar to how they're represented in Prometheus format
DecomposeOtlpHistograms bool `mapstructure:"decompose_otlp_histograms"`

// Sumo specific options
// Name of the client
Client string `mapstructure:"client"`

Expand All @@ -66,6 +72,30 @@ func createDefaultClientConfig() confighttp.ClientConfig {
}

func (cfg *Config) Validate() error {

switch cfg.CompressEncoding {
case configcompression.TypeGzip:
case configcompression.TypeDeflate:
case NoCompression:

default:
return fmt.Errorf("invalid compression encoding type: %v", cfg.CompressEncoding)
}

switch cfg.ClientConfig.Compression {
case configcompression.TypeGzip:
case configcompression.TypeDeflate:
case configcompression.TypeZstd:
case NoCompression:

default:
return fmt.Errorf("invalid compression encoding type: %v", cfg.ClientConfig.Compression)
}

if cfg.CompressEncoding != NoCompression && cfg.ClientConfig.Compression != DefaultCompressEncoding {
return fmt.Errorf("compress_encoding is deprecated and should not be used when compression is set to a non-default value")
}

switch cfg.LogFormat {
case OTLPLogFormat:
case JSONFormat:
Expand All @@ -75,26 +105,16 @@ func (cfg *Config) Validate() error {
}

switch cfg.MetricFormat {
case OTLPMetricFormat:
case PrometheusFormat:
case RemovedGraphiteFormat:
return fmt.Errorf("support for the graphite metric format was removed, please use prometheus or otlp instead")
case RemovedCarbon2Format:
return fmt.Errorf("support for the carbon2 metric format was removed, please use prometheus or otlp instead")
case PrometheusFormat:
case OTLPMetricFormat:
default:
return fmt.Errorf("unexpected metric format: %s", cfg.MetricFormat)
}

switch cfg.ClientConfig.Compression {
case configcompression.TypeGzip:
case configcompression.TypeDeflate:
case configcompression.TypeZstd:
case NoCompression:

default:
return fmt.Errorf("invalid compression encoding type: %v", cfg.ClientConfig.Compression)
}

if len(cfg.ClientConfig.Endpoint) == 0 && cfg.ClientConfig.Auth == nil {
return errors.New("no endpoint and no auth extension specified")
}
Expand All @@ -118,35 +138,39 @@ type LogFormatType string
// MetricFormatType represents metric_format
type MetricFormatType string

// TraceFormatType represents trace_format
type TraceFormatType string

// PipelineType represents type of the pipeline
type PipelineType string

// CompressEncodingType represents type of the pipeline
type CompressEncodingType string

const (
// TextFormat represents log_format: text
TextFormat LogFormatType = "text"
// JSONFormat represents log_format: json
JSONFormat LogFormatType = "json"
// RemovedGraphiteFormat represents the no longer supported graphite metric format
// OTLPLogFormat represents log_format: otlp
OTLPLogFormat LogFormatType = "otlp"
// RemovedGraphiteFormat represents the no longer supported graphite metric format
RemovedGraphiteFormat MetricFormatType = "graphite"
// RemovedCarbon2Format represents the no longer supported carbon2 metric format
RemovedCarbon2Format MetricFormatType = "carbon2"
// GraphiteFormat represents metric_format: text
// PrometheusFormat represents metric_format: prometheus
PrometheusFormat MetricFormatType = "prometheus"
// OTLPMetricFormat represents metric_format: otlp
OTLPMetricFormat MetricFormatType = "otlp"
// OTLPTraceFormat represents trace_format: otlp
OTLPTraceFormat TraceFormatType = "otlp"
// NoCompression represents disabled compression
NoCompression configcompression.Type = ""
// MetricsPipeline represents metrics pipeline
MetricsPipeline PipelineType = "metrics"
// LogsPipeline represents metrics pipeline
LogsPipeline PipelineType = "logs"
// TracesPipeline represents traces pipeline
TracesPipeline PipelineType = "traces"
// defaultTimeout
defaultTimeout time.Duration = 5 * time.Second
defaultTimeout time.Duration = 30 * time.Second
// DefaultCompress defines default Compress
DefaultCompress bool = true
// DefaultCompressEncoding defines default CompressEncoding
Expand All @@ -157,12 +181,6 @@ const (
DefaultLogFormat LogFormatType = OTLPLogFormat
// DefaultMetricFormat defines default MetricFormat
DefaultMetricFormat MetricFormatType = OTLPMetricFormat
// DefaultSourceCategory defines default SourceCategory
DefaultSourceCategory string = ""
// DefaultSourceName defines default SourceName
DefaultSourceName string = ""
// DefaultSourceHost defines default SourceHost
DefaultSourceHost string = ""
// DefaultClient defines default Client
DefaultClient string = "otelcol"
// DefaultLogKey defines default LogKey value
Expand Down
14 changes: 1 addition & 13 deletions exporter/sumologicexporter/config_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package sumologicexporter
package sumologicexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/sumologicexporter"

import (
"errors"
Expand Down Expand Up @@ -69,18 +69,6 @@ func TestInitExporterInvalidConfiguration(t *testing.T) {
},
},
},
{
name: "no endpoint and no auth extension specified",
expectedError: errors.New("no endpoint and no auth extension specified"),
cfg: &Config{
LogFormat: "json",
MetricFormat: "otlp",
ClientConfig: confighttp.ClientConfig{
Timeout: defaultTimeout,
Compression: "gzip",
},
},
},
}

for _, tc := range testcases {
Expand Down
43 changes: 43 additions & 0 deletions exporter/sumologicexporter/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/pdata/plog"
"go.opentelemetry.io/collector/pdata/pmetric"
"go.opentelemetry.io/collector/pdata/ptrace"
"go.uber.org/zap"

"github.com/open-telemetry/opentelemetry-collector-contrib/extension/sumologicextension"
Expand Down Expand Up @@ -120,6 +121,28 @@ func newMetricsExporter(
)
}

func newTracesExporter(
ctx context.Context,
params exporter.CreateSettings,
cfg *Config,
) (exporter.Traces, error) {
se := initExporter(cfg, params)

return exporterhelper.NewTracesExporter(
ctx,
params,
cfg,
se.pushTracesData,
// Disable exporterhelper Timeout, since we are using a custom mechanism
// within exporter itself
exporterhelper.WithTimeout(exporterhelper.TimeoutSettings{Timeout: 0}),
exporterhelper.WithRetry(cfg.BackOffConfig),
exporterhelper.WithQueue(cfg.QueueSettings),
exporterhelper.WithStart(se.start),
exporterhelper.WithShutdown(se.shutdown),
)
}

// start starts the exporter
func (se *sumologicexporter) start(ctx context.Context, host component.Host) (err error) {
se.host = host
Expand Down Expand Up @@ -374,6 +397,26 @@ func (se *sumologicexporter) handleUnauthorizedErrors(ctx context.Context, errs
}
}

func (se *sumologicexporter) pushTracesData(ctx context.Context, td ptrace.Traces) error {
logsURL, metricsURL, tracesURL := se.getDataURLs()
sdr := newSender(
se.logger,
se.config,
se.getHTTPClient(),
se.prometheusFormatter,
metricsURL,
logsURL,
tracesURL,
se.StickySessionCookie,
se.SetStickySessionCookie,
se.id,
)

err := sdr.sendTraces(ctx, td)
se.handleUnauthorizedErrors(ctx, err)
return err
}

func (se *sumologicexporter) StickySessionCookie() string {
if se.foundSumologicExtension {
return se.sumologicExtension.StickySessionCookie()
Expand Down
Loading

0 comments on commit cab59ab

Please sign in to comment.