@cryptotaxi247 / netdata-1 / commits / a6036dfac

remove otel coll dist (#21714)

Ilya Mashchenko committed Feb 5, 2026 at 20:35 UTC a6036dfac0e59482a96e2cd17bd2ebfd7cdefda1
34 files changed -4240
src/go/otel-collector/CMakeLists.txt deleted
-58
@@ -1,58 +0,0 @@
1 -# SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -function(_handle_otel)
4 - if(CMAKE_BUILD_TYPE STREQUAL Debug)
5 - set(DEBUG_BUILD True)
6 - else()
7 - set(DEBUG_BUILD False)
8 - endif()
9 -
10 - message(STATUS "Generating OpenTelemetry Collector Builder configuration")
11 - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/release-config.yaml.in"
12 - "${CMAKE_BINARY_DIR}/otel-build-config.yaml"
13 - @ONLY)
14 - message(STATUS "Generating OpenTelemetry Collector Builder configuration -- Done")
15 -
16 - message(STATUS "Fetching OpenTelemetry Collector Builder")
17 - set(OLD_GOBIN $ENV{GOBIN})
18 - set(ENV{GOBIN} ${CMAKE_BINARY_DIR}/bin)
19 - execute_process(
20 - COMMAND ${GO_EXECUTABLE} install go.opentelemetry.io/collector/cmd/builder@latest
21 - RESULT_VARIABLE otel_builder_install
22 - )
23 - set(ENV{GOBIN} ${OLD_GOBIN})
24 -
25 - if(otel_builder_install)
26 - message(FATAL_ERROR "Fetching OpenTelemetry Collector Builder --Failed")
27 - else()
28 - message(STATUS "Fetching OpenTelemetry Collector Builder -- Success")
29 - endif()
30 -
31 - set(DIRS "exporter/journaldexporter")
32 - set(otelcol_deps "")
33 -
34 - foreach(dir IN LISTS DIRS)
35 - file(GLOB_RECURSE deps CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*.go")
36 - list(APPEND otelcol_deps "${deps}")
37 - list(APPEND otelcol_deps
38 - "${CMAKE_CURRENT_SOURCE_DIR}/${dir}/go.mod"
39 - "${CMAKE_CURRENT_SOURCE_DIR}/${dir}/go.sum"
40 - )
41 - endforeach()
42 -
43 - add_custom_command(
44 - OUTPUT otel-collector/otelcol.plugin
45 - COMMAND ${CMAKE_BINARY_DIR}/bin/builder --config=${CMAKE_BINARY_DIR}/otel-build-config.yaml
46 - DEPENDS ${otelcol_deps}
47 - COMMENT "Building otelcol.plugin"
48 - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
49 - VERBATIM
50 - )
51 -
52 - add_custom_target(
53 - plugin-otelcol ALL
54 - DEPENDS otel-collector/otelcol.plugin
55 - )
56 -endfunction()
57 -
58 -_handle_otel()
src/go/otel-collector/README.md deleted
-14
@@ -1,14 +0,0 @@
1 -# Netdata OpenTelemetry Collector
2 -
3 -A custom distribution of the OpenTelemetry Collector maintained by Netdata.
4 -
5 -Based on the official OpenTelemetry Collector, this distribution maintains upstream compatibility while providing specialized components designed for Netdata environments. All custom components are maintained and distributed within this repository.
6 -
7 -## Build
8 -
9 -```bash
10 -go install go.opentelemetry.io/collector/cmd/builder@latest
11 -cd src/go/otel-collector
12 -builder --config=builder-config.yaml
13 -build/otelcol.plugin
14 -```
src/go/otel-collector/builder-config.yaml deleted
-25
@@ -1,25 +0,0 @@
1 -dist:
2 - name: otelcol.plugin
3 - module: github.com/netdata/netdata/otel-collector
4 - description: OpenTelemetry Collector Distribution built for Netdata
5 - output_path: ./build
6 - version: 0.0.0
7 - debug_compilation: false
8 -
9 -receivers:
10 - - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.137.0
11 - - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver v0.137.0
12 - - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver v0.137.0
13 - - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver v0.137.0
14 -
15 -exporters:
16 - - gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.137.0
17 - - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter v0.137.0
18 - - gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.137.0
19 - - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/prometheusexporter v0.137.0
20 - - gomod: github.com/netdata/netdata/otel-collector/exporter/journaldexporter v0.0.0
21 - - gomod: github.com/netdata/netdata/otel-collector/exporter/netdataexporter v0.0.0
22 -
23 -replaces:
24 - - github.com/netdata/netdata/otel-collector/exporter/journaldexporter => ../exporter/journaldexporter
25 - - github.com/netdata/netdata/otel-collector/exporter/netdataexporter => ../exporter/netdataexporter
src/go/otel-collector/exporter/journaldexporter/config.go deleted
-26
@@ -1,26 +0,0 @@
1 -// SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -package journaldexporter
4 -
5 -import (
6 - "time"
7 -
8 - "go.opentelemetry.io/collector/component"
9 -)
10 -
11 -type Config struct {
12 - URL string `mapstructure:"url"`
13 - Timeout time.Duration `mapstructure:"timeout"`
14 - TLS struct {
15 - SrvCertFile string `mapstructure:"server_certificate_file"`
16 - SrvKeyFile string `mapstructure:"server_key_file"`
17 - TrustedCertFile string `mapstructure:"trusted_certificate_file"`
18 - InsecureSkipVerify bool `mapstructure:"insecure_skip_verify"`
19 - } `mapstructure:"tls"`
20 -}
21 -
22 -var _ component.Config = (*Config)(nil)
23 -
24 -func (cfg *Config) Validate() error {
25 - return nil
26 -}
src/go/otel-collector/exporter/journaldexporter/convert.go deleted
-142
@@ -1,142 +0,0 @@
1 -// SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -package journaldexporter
4 -
5 -import (
6 - "bytes"
7 - "encoding/binary"
8 - "fmt"
9 - "strconv"
10 - "strings"
11 - "time"
12 -
13 - "go.opentelemetry.io/collector/pdata/pcommon"
14 - "go.opentelemetry.io/collector/pdata/plog"
15 -)
16 -
17 -func (e *journaldExporter) logsToJournaldMessages(ld plog.Logs, buf *bytes.Buffer) {
18 - receivedAt := fmt.Sprintf("%d", time.Now().UnixNano()/1000)
19 -
20 - for _, rl := range ld.ResourceLogs().All() {
21 - resource := rl.Resource()
22 -
23 - for _, sl := range rl.ScopeLogs().All() {
24 - scope := sl.Scope()
25 -
26 - for _, lr := range sl.LogRecords().All() {
27 - writeField(buf, "__REALTIME_TIMESTAMP", receivedAt)
28 - writeField(buf, "SYSLOG_IDENTIFIER", e.fields.syslogID)
29 - writeField(buf, "_PID", e.fields.pid)
30 - writeField(buf, "_UID", e.fields.uid)
31 - writeField(buf, "_BOOT_ID", e.fields.bootID)
32 - writeField(buf, "_MACHINE_ID", e.fields.machineID)
33 - writeField(buf, "_HOSTNAME", e.fields.hostname)
34 - writeField(buf, "PRIORITY", strconv.Itoa(mapSeverityToJournaldPriority(lr.SeverityNumber())))
35 - writeField(buf, "MESSAGE", bodyToString(lr.Body()))
36 -
37 - for k, v := range resource.Attributes().All() {
38 - writeField(buf, "OTEL_RESOURCE_ATTR_"+k, v.AsString())
39 - }
40 -
41 - writeField(buf, "OTEL_SCOPE_NAME", scope.Name())
42 - writeField(buf, "OTEL_SCOPE_VERSION", scope.Version())
43 -
44 - if lr.Timestamp() != 0 {
45 - ts := time.Unix(0, int64(lr.Timestamp()))
46 - writeField(buf, "OTEL_TIMESTAMP", strconv.FormatInt(ts.UnixMicro(), 10))
47 - }
48 - if lr.ObservedTimestamp() != 0 {
49 - ts := time.Unix(0, int64(lr.ObservedTimestamp()))
50 - writeField(buf, "OTEL_OBSERVED_TIMESTAMP", strconv.FormatInt(ts.UnixMicro(), 10))
51 - }
52 -
53 - writeField(buf, "OTEL_SEVERITY_LEVEL", lr.SeverityText())
54 -
55 - if !lr.TraceID().IsEmpty() {
56 - writeField(buf, "OTEL_TRACE_ID", lr.TraceID().String())
57 - if !lr.SpanID().IsEmpty() {
58 - writeField(buf, "OTEL_SPAN_ID", lr.SpanID().String())
59 - }
60 - if lr.Flags() != 0 {
61 - writeField(buf, "OTEL_TRACE_FLAGS", strconv.FormatUint(uint64(lr.Flags()), 16))
62 - }
63 - }
64 -
65 - writeField(buf, "OTEL_EVENT_NAME", lr.EventName())
66 -
67 - for k, v := range lr.Attributes().All() {
68 - writeField(buf, "OTEL_ATTR_"+k, v.AsString())
69 - }
70 -
71 - buf.WriteByte('\n') // extra newline
72 - }
73 - }
74 - }
75 -}
76 -
77 -func mapSeverityToJournaldPriority(severity plog.SeverityNumber) int {
78 - switch {
79 - case severity >= plog.SeverityNumberFatal && severity <= plog.SeverityNumberFatal4:
80 - return 2 // critical
81 - case severity >= plog.SeverityNumberError && severity <= plog.SeverityNumberError4:
82 - return 3 // error
83 - case severity >= plog.SeverityNumberWarn && severity <= plog.SeverityNumberWarn4:
84 - return 4 // warning
85 - case severity >= plog.SeverityNumberInfo && severity <= plog.SeverityNumberInfo4:
86 - return 6 // info
87 - case severity >= plog.SeverityNumberDebug && severity <= plog.SeverityNumberDebug4:
88 - return 7 // debug
89 - case severity >= plog.SeverityNumberTrace && severity <= plog.SeverityNumberTrace4:
90 - return 7 // debug (journald doesn't have trace)
91 - default:
92 - return 6 // info as default
93 - }
94 -}
95 -
96 -func bodyToString(body pcommon.Value) string {
97 - switch body.Type() {
98 - case pcommon.ValueTypeEmpty:
99 - return ""
100 - case pcommon.ValueTypeStr:
101 - return body.Str()
102 - default:
103 - return body.AsString()
104 - }
105 -}
106 -
107 -func writeField(buf *bytes.Buffer, name, value string) {
108 - if value == "" {
109 - return
110 - }
111 - normalizedName := normalizeFieldName(name)
112 -
113 - if strings.ContainsRune(value, '\n') {
114 - buf.WriteString(normalizedName)
115 - buf.WriteByte('\n')
116 - _ = binary.Write(buf, binary.LittleEndian, uint64(len(value)))
117 - buf.WriteString(value)
118 - buf.WriteByte('\n')
119 - } else {
120 - buf.WriteString(normalizedName)
121 - buf.WriteByte('=')
122 - buf.WriteString(value)
123 - buf.WriteByte('\n')
124 - }
125 -}
126 -
127 -func normalizeFieldName(name string) string {
128 - // Journald field names can only contain uppercase letters, numbers, and underscores
129 - // Replace any character that isn't A-Z, 0-9, or _ with _
130 - normalized := strings.Map(func(r rune) rune {
131 - if (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') || r == '_' {
132 - return r
133 - }
134 - if r >= 'a' && r <= 'z' {
135 - return r - 32 // Convert to uppercase
136 - }
137 - return '_'
138 - }, name)
139 -
140 - // Journald field names must be uppercase
141 - return strings.ToUpper(normalized)
142 -}
src/go/otel-collector/exporter/journaldexporter/convert_test.go deleted
-177
@@ -1,177 +0,0 @@
1 -// SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -package journaldexporter
4 -
5 -import (
6 - "bytes"
7 - "encoding/binary"
8 - "strings"
9 - "testing"
10 - "time"
11 -
12 - "github.com/stretchr/testify/assert"
13 - "go.opentelemetry.io/collector/pdata/pcommon"
14 - "go.opentelemetry.io/collector/pdata/plog"
15 -)
16 -
17 -func TestLogsToJournaldMessages(t *testing.T) {
18 - type testCase struct {
19 - logsFn func() plog.Logs
20 - expected string
21 - }
22 -
23 - tests := map[string]testCase{
24 - "simple log with basic fields": {
25 - logsFn: func() plog.Logs {
26 - logs := plog.NewLogs()
27 - rl := logs.ResourceLogs().AppendEmpty()
28 -
29 - rl.Resource().Attributes().PutStr("service.name", "test-service")
30 - rl.Resource().Attributes().PutStr("service.instance.id", "instance-1")
31 -
32 - sl := rl.ScopeLogs().AppendEmpty()
33 - sl.Scope().SetName("test-scope")
34 - sl.Scope().SetVersion("v1.0.0")
35 -
36 - lr := sl.LogRecords().AppendEmpty()
37 - lr.SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(1617030613, 0))) // 2021-03-29T12:23:33Z
38 - lr.SetSeverityNumber(plog.SeverityNumberInfo)
39 - lr.SetSeverityText("INFO")
40 - lr.Body().SetStr("This is a test message")
41 -
42 - lr.Attributes().PutStr("http.method", "GET")
43 - lr.Attributes().PutInt("http.status_code", 200)
44 -
45 - return logs
46 - },
47 - expected: `__REALTIME_TIMESTAMP=
48 -SYSLOG_IDENTIFIER=test-syslog-id
49 -_PID=test-pid
50 -_UID=test-uid
51 -_BOOT_ID=test-boot-id
52 -_MACHINE_ID=test-machine-id
53 -_HOSTNAME=test-hostname
54 -PRIORITY=6
55 -MESSAGE=This is a test message
56 -OTEL_RESOURCE_ATTR_SERVICE_NAME=test-service
57 -OTEL_RESOURCE_ATTR_SERVICE_INSTANCE_ID=instance-1
58 -OTEL_SCOPE_NAME=test-scope
59 -OTEL_SCOPE_VERSION=v1.0.0
60 -OTEL_TIMESTAMP=1617030613000000
61 -OTEL_SEVERITY_LEVEL=INFO
62 -OTEL_ATTR_HTTP_METHOD=GET
63 -OTEL_ATTR_HTTP_STATUS_CODE=200
64 -
65 -`,
66 - },
67 - "log with trace context": {
68 - logsFn: func() plog.Logs {
69 - logs := plog.NewLogs()
70 - rl := logs.ResourceLogs().AppendEmpty()
71 - sl := rl.ScopeLogs().AppendEmpty()
72 - lr := sl.LogRecords().AppendEmpty()
73 -
74 - lr.SetSeverityNumber(plog.SeverityNumberError)
75 - lr.SetSeverityText("ERROR")
76 - lr.Body().SetStr("Connection failed")
77 -
78 - traceID := pcommon.TraceID([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16})
79 - spanID := pcommon.SpanID([8]byte{1, 2, 3, 4, 5, 6, 7, 8})
80 - lr.SetTraceID(traceID)
81 - lr.SetSpanID(spanID)
82 - lr.SetFlags(1) // Sampled flag
83 -
84 - return logs
85 - },
86 - expected: `__REALTIME_TIMESTAMP=
87 -SYSLOG_IDENTIFIER=test-syslog-id
88 -_PID=test-pid
89 -_UID=test-uid
90 -_BOOT_ID=test-boot-id
91 -_MACHINE_ID=test-machine-id
92 -_HOSTNAME=test-hostname
93 -PRIORITY=3
94 -MESSAGE=Connection failed
95 -OTEL_SEVERITY_LEVEL=ERROR
96 -OTEL_TRACE_ID=0102030405060708090a0b0c0d0e0f10
97 -OTEL_SPAN_ID=0102030405060708
98 -OTEL_TRACE_FLAGS=1
99 -
100 -`,
101 - },
102 - "log with multiline message": {
103 - logsFn: func() plog.Logs {
104 - logs := plog.NewLogs()
105 - rl := logs.ResourceLogs().AppendEmpty()
106 - sl := rl.ScopeLogs().AppendEmpty()
107 - lr := sl.LogRecords().AppendEmpty()
108 -
109 - lr.SetSeverityNumber(plog.SeverityNumberError)
110 - lr.Body().SetStr("Error occurred:\nStack trace:\n at function1()\n at function2()\n at main()")
111 -
112 - return logs
113 - },
114 - expected: func() string {
115 - var buf bytes.Buffer
116 - buf.WriteString("__REALTIME_TIMESTAMP=\n")
117 - buf.WriteString("SYSLOG_IDENTIFIER=test-syslog-id\n")
118 - buf.WriteString("_PID=test-pid\n")
119 - buf.WriteString("_UID=test-uid\n")
120 - buf.WriteString("_BOOT_ID=test-boot-id\n")
121 - buf.WriteString("_MACHINE_ID=test-machine-id\n")
122 - buf.WriteString("_HOSTNAME=test-hostname\n")
123 - buf.WriteString("PRIORITY=3\n")
124 - buf.WriteString("MESSAGE\n")
125 - multilineMsg := "Error occurred:\nStack trace:\n at function1()\n at function2()\n at main()"
126 - _ = binary.Write(&buf, binary.LittleEndian, uint64(len(multilineMsg)))
127 - buf.WriteString(multilineMsg)
128 - buf.WriteString("\n\n")
129 - return buf.String()
130 - }(),
131 - },
132 - }
133 -
134 - for name, tc := range tests {
135 - t.Run(name, func(t *testing.T) {
136 - var buf bytes.Buffer
137 - e := journaldExporter{fields: commonFields{
138 - syslogID: "test-syslog-id",
139 - pid: "test-pid",
140 - uid: "test-uid",
141 - hostname: "test-hostname",
142 - bootID: "test-boot-id",
143 - machineID: "test-machine-id",
144 - }}
145 -
146 - e.logsToJournaldMessages(tc.logsFn(), &buf)
147 -
148 - ts, _, _ := strings.Cut(buf.String(), "\n")
149 - _, expected, _ := strings.Cut(tc.expected, "\n")
150 -
151 - assert.Equal(t, ts+"\n"+expected, buf.String())
152 - })
153 - }
154 -}
155 -
156 -func TestMappingSeverity(t *testing.T) {
157 - tests := map[string]struct {
158 - severity plog.SeverityNumber
159 - expected int
160 - }{
161 - "undefined": {severity: plog.SeverityNumberUnspecified, expected: 6},
162 - "trace": {severity: plog.SeverityNumberTrace, expected: 7},
163 - "trace2": {severity: plog.SeverityNumberTrace2, expected: 7},
164 - "debug": {severity: plog.SeverityNumberDebug, expected: 7},
165 - "info": {severity: plog.SeverityNumberInfo, expected: 6},
166 - "warn": {severity: plog.SeverityNumberWarn, expected: 4},
167 - "error": {severity: plog.SeverityNumberError, expected: 3},
168 - "fatal": {severity: plog.SeverityNumberFatal, expected: 2},
169 - }
170 -
171 - for name, tc := range tests {
172 - t.Run(name, func(t *testing.T) {
173 - result := mapSeverityToJournaldPriority(tc.severity)
174 - assert.Equal(t, tc.expected, result)
175 - })
176 - }
177 -}
src/go/otel-collector/exporter/journaldexporter/doc.go deleted
-3
@@ -1,3 +0,0 @@
1 -//go:generate mdatagen metadata.yaml
2 -
3 -package journaldexporter
src/go/otel-collector/exporter/journaldexporter/exporter.go deleted
-81
@@ -1,81 +0,0 @@
1 -// SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -package journaldexporter
4 -
5 -import (
6 - "bytes"
7 - "context"
8 - "fmt"
9 - "os"
10 - "os/user"
11 - "strconv"
12 -
13 - "go.opentelemetry.io/collector/component"
14 - "go.opentelemetry.io/collector/pdata/plog"
15 - "go.uber.org/zap"
16 -)
17 -
18 -type (
19 - journaldExporter struct {
20 - log *zap.Logger
21 - conf *Config
22 - fields commonFields
23 - s sender
24 - buf bytes.Buffer
25 - }
26 - sender interface {
27 - sendMessage(ctx context.Context, msg []byte) error
28 - shutdown(ctx context.Context) error
29 - }
30 -
31 - commonFields struct {
32 - syslogID string
33 - pid string
34 - uid string
35 - bootID string
36 - machineID string
37 - hostname string
38 - }
39 -)
40 -
41 -func newJournaldExporter(cfg component.Config, logger *zap.Logger) *journaldExporter {
42 - return &journaldExporter{
43 - log: logger,
44 - conf: cfg.(*Config),
45 - }
46 -}
47 -
48 -func (e *journaldExporter) consumeLogs(ctx context.Context, ld plog.Logs) error {
49 - if e.s == nil {
50 - return nil
51 - }
52 -
53 - e.buf.Reset()
54 -
55 - e.logsToJournaldMessages(ld, &e.buf)
56 -
57 - select {
58 - case <-ctx.Done():
59 - return nil
60 - default:
61 - return e.s.sendMessage(ctx, e.buf.Bytes())
62 - }
63 -}
64 -
65 -func (e *journaldExporter) Start(_ context.Context, _ component.Host) error {
66 - e.fields.syslogID = "nd-otel-collector"
67 - e.fields.pid = strconv.Itoa(os.Getpid())
68 - e.fields.hostname, _ = os.Hostname()
69 - e.fields.bootID = getBootID()
70 - e.fields.machineID = getMachineID()
71 - if cu, err := user.Current(); err == nil {
72 - e.fields.uid = cu.Uid
73 - }
74 -
75 - return nil
76 -}
77 -
78 -func (e *journaldExporter) Shutdown(context.Context) error {
79 - fmt.Println("Shutting down MyExporter")
80 - return nil
81 -}
src/go/otel-collector/exporter/journaldexporter/factory.go deleted
-41
@@ -1,41 +0,0 @@
1 -// SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -package journaldexporter
4 -
5 -import (
6 - "context"
7 -
8 - "go.opentelemetry.io/collector/component"
9 - "go.opentelemetry.io/collector/consumer"
10 - "go.opentelemetry.io/collector/exporter"
11 - "go.opentelemetry.io/collector/exporter/exporterhelper"
12 - "go.opentelemetry.io/collector/exporter/xexporter"
13 -
14 - "github.com/netdata/netdata/otel-collector/exporter/journaldexporter/internal/metadata"
15 -)
16 -
17 -func NewFactory() exporter.Factory {
18 - return xexporter.NewFactory(
19 - metadata.Type,
20 - createDefaultConfig,
21 - xexporter.WithLogs(createLogsExporter, metadata.LogsStability),
22 - )
23 -}
24 -
25 -func createDefaultConfig() component.Config {
26 - return &Config{}
27 -}
28 -
29 -func createLogsExporter(ctx context.Context, set exporter.Settings, cfg component.Config) (exporter.Logs, error) {
30 - exp := newJournaldExporter(cfg, set.Logger)
31 -
32 - return exporterhelper.NewLogs(
33 - ctx,
34 - set,
35 - cfg,
36 - exp.consumeLogs,
37 - exporterhelper.WithStart(exp.Start),
38 - exporterhelper.WithShutdown(exp.Shutdown),
39 - exporterhelper.WithCapabilities(consumer.Capabilities{MutatesData: false}),
40 - )
41 -}
src/go/otel-collector/exporter/journaldexporter/generated_component_test.go deleted
-138
@@ -1,138 +0,0 @@
1 -// Code generated by mdatagen. DO NOT EDIT.
2 -
3 -package journaldexporter
4 -
5 -import (
6 - "context"
7 - "testing"
8 - "time"
9 -
10 - "github.com/stretchr/testify/require"
11 - "go.opentelemetry.io/collector/component"
12 - "go.opentelemetry.io/collector/component/componenttest"
13 - "go.opentelemetry.io/collector/confmap/confmaptest"
14 - "go.opentelemetry.io/collector/exporter"
15 - "go.opentelemetry.io/collector/exporter/exportertest"
16 - "go.opentelemetry.io/collector/pdata/pcommon"
17 - "go.opentelemetry.io/collector/pdata/plog"
18 - "go.opentelemetry.io/collector/pdata/pmetric"
19 - "go.opentelemetry.io/collector/pdata/ptrace"
20 -)
21 -
22 -var typ = component.MustNewType("journaldexporter")
23 -
24 -func TestComponentFactoryType(t *testing.T) {
25 - require.Equal(t, typ, NewFactory().Type())
26 -}
27 -
28 -func TestComponentConfigStruct(t *testing.T) {
29 - require.NoError(t, componenttest.CheckConfigStruct(NewFactory().CreateDefaultConfig()))
30 -}
31 -
32 -func TestComponentLifecycle(t *testing.T) {
33 - factory := NewFactory()
34 -
35 - tests := []struct {
36 - createFn func(ctx context.Context, set exporter.Settings, cfg component.Config) (component.Component, error)
37 - name string
38 - }{
39 -
40 - {
41 - name: "logs",
42 - createFn: func(ctx context.Context, set exporter.Settings, cfg component.Config) (component.Component, error) {
43 - return factory.CreateLogs(ctx, set, cfg)
44 - },
45 - },
46 - }
47 -
48 - cm, err := confmaptest.LoadConf("metadata.yaml")
49 - require.NoError(t, err)
50 - cfg := factory.CreateDefaultConfig()
51 - sub, err := cm.Sub("tests::config")
52 - require.NoError(t, err)
53 - require.NoError(t, sub.Unmarshal(&cfg))
54 -
55 - for _, tt := range tests {
56 - t.Run(tt.name+"-shutdown", func(t *testing.T) {
57 - c, err := tt.createFn(context.Background(), exportertest.NewNopSettings(typ), cfg)
58 - require.NoError(t, err)
59 - err = c.Shutdown(context.Background())
60 - require.NoError(t, err)
61 - })
62 - t.Run(tt.name+"-lifecycle", func(t *testing.T) {
63 - c, err := tt.createFn(context.Background(), exportertest.NewNopSettings(typ), cfg)
64 - require.NoError(t, err)
65 - host := componenttest.NewNopHost()
66 - err = c.Start(context.Background(), host)
67 - require.NoError(t, err)
68 - require.NotPanics(t, func() {
69 - switch tt.name {
70 - case "logs":
71 - e, ok := c.(exporter.Logs)
72 - require.True(t, ok)
73 - logs := generateLifecycleTestLogs()
74 - if !e.Capabilities().MutatesData {
75 - logs.MarkReadOnly()
76 - }
77 - err = e.ConsumeLogs(context.Background(), logs)
78 - case "metrics":
79 - e, ok := c.(exporter.Metrics)
80 - require.True(t, ok)
81 - metrics := generateLifecycleTestMetrics()
82 - if !e.Capabilities().MutatesData {
83 - metrics.MarkReadOnly()
84 - }
85 - err = e.ConsumeMetrics(context.Background(), metrics)
86 - case "traces":
87 - e, ok := c.(exporter.Traces)
88 - require.True(t, ok)
89 - traces := generateLifecycleTestTraces()
90 - if !e.Capabilities().MutatesData {
91 - traces.MarkReadOnly()
92 - }
93 - err = e.ConsumeTraces(context.Background(), traces)
94 - }
95 - })
96 -
97 - require.NoError(t, err)
98 -
99 - err = c.Shutdown(context.Background())
100 - require.NoError(t, err)
101 - })
102 - }
103 -}
104 -
105 -func generateLifecycleTestLogs() plog.Logs {
106 - logs := plog.NewLogs()
107 - rl := logs.ResourceLogs().AppendEmpty()
108 - rl.Resource().Attributes().PutStr("resource", "R1")
109 - l := rl.ScopeLogs().AppendEmpty().LogRecords().AppendEmpty()
110 - l.Body().SetStr("test log message")
111 - l.SetTimestamp(pcommon.NewTimestampFromTime(time.Now()))
112 - return logs
113 -}
114 -
115 -func generateLifecycleTestMetrics() pmetric.Metrics {
116 - metrics := pmetric.NewMetrics()
117 - rm := metrics.ResourceMetrics().AppendEmpty()
118 - rm.Resource().Attributes().PutStr("resource", "R1")
119 - m := rm.ScopeMetrics().AppendEmpty().Metrics().AppendEmpty()
120 - m.SetName("test_metric")
121 - dp := m.SetEmptyGauge().DataPoints().AppendEmpty()
122 - dp.Attributes().PutStr("test_attr", "value_1")
123 - dp.SetIntValue(123)
124 - dp.SetTimestamp(pcommon.NewTimestampFromTime(time.Now()))
125 - return metrics
126 -}
127 -
128 -func generateLifecycleTestTraces() ptrace.Traces {
129 - traces := ptrace.NewTraces()
130 - rs := traces.ResourceSpans().AppendEmpty()
131 - rs.Resource().Attributes().PutStr("resource", "R1")
132 - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty()
133 - span.Attributes().PutStr("test_attr", "value_1")
134 - span.SetName("test_span")
135 - span.SetStartTimestamp(pcommon.NewTimestampFromTime(time.Now().Add(-1 * time.Second)))
136 - span.SetEndTimestamp(pcommon.NewTimestampFromTime(time.Now()))
137 - return traces
138 -}
src/go/otel-collector/exporter/journaldexporter/generated_package_test.go deleted
-12
@@ -1,12 +0,0 @@
1 -// Code generated by mdatagen. DO NOT EDIT.
2 -
3 -package journaldexporter
4 -
5 -import (
6 - "go.uber.org/goleak"
7 - "testing"
8 -)
9 -
10 -func TestMain(m *testing.M) {
11 - goleak.VerifyTestMain(m)
12 -}
src/go/otel-collector/exporter/journaldexporter/go.mod deleted
-73
@@ -1,73 +0,0 @@
1 -module github.com/netdata/netdata/otel-collector/exporter/journaldexporter
2 -
3 -go 1.24.0
4 -
5 -require (
6 - github.com/google/uuid v1.6.0
7 - github.com/stretchr/testify v1.11.1
8 - go.opentelemetry.io/collector/component v1.43.0
9 - go.opentelemetry.io/collector/component/componenttest v0.137.0
10 - go.opentelemetry.io/collector/confmap v1.43.0
11 - go.opentelemetry.io/collector/consumer v1.43.0
12 - go.opentelemetry.io/collector/exporter v1.43.0
13 - go.opentelemetry.io/collector/exporter/exporterhelper v0.137.0
14 - go.opentelemetry.io/collector/exporter/exportertest v0.137.0
15 - go.opentelemetry.io/collector/exporter/xexporter v0.137.0
16 - go.opentelemetry.io/collector/pdata v1.43.0
17 - go.uber.org/goleak v1.3.0
18 - go.uber.org/zap v1.27.0
19 -)
20 -
21 -require (
22 - github.com/cenkalti/backoff/v5 v5.0.3 // indirect
23 - github.com/davecgh/go-spew v1.1.1 // indirect
24 - github.com/go-logr/logr v1.4.3 // indirect
25 - github.com/go-logr/stdr v1.2.2 // indirect
26 - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
27 - github.com/gobwas/glob v0.2.3 // indirect
28 - github.com/gogo/protobuf v1.3.2 // indirect
29 - github.com/hashicorp/go-version v1.7.0 // indirect
30 - github.com/json-iterator/go v1.1.12 // indirect
31 - github.com/knadh/koanf/maps v0.1.2 // indirect
32 - github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
33 - github.com/knadh/koanf/v2 v2.3.0 // indirect
34 - github.com/mitchellh/copystructure v1.2.0 // indirect
35 - github.com/mitchellh/reflectwalk v1.0.2 // indirect
36 - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
37 - github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
38 - github.com/pmezard/go-difflib v1.0.0 // indirect
39 - go.opentelemetry.io/auto/sdk v1.2.1 // indirect
40 - go.opentelemetry.io/collector/client v1.43.0 // indirect
41 - go.opentelemetry.io/collector/config/configoptional v1.43.0 // indirect
42 - go.opentelemetry.io/collector/config/configretry v1.43.0 // indirect
43 - go.opentelemetry.io/collector/confmap/xconfmap v0.137.0 // indirect
44 - go.opentelemetry.io/collector/consumer/consumererror v0.137.0 // indirect
45 - go.opentelemetry.io/collector/consumer/consumertest v0.137.0 // indirect
46 - go.opentelemetry.io/collector/consumer/xconsumer v0.137.0 // indirect
47 - go.opentelemetry.io/collector/extension v1.43.0 // indirect
48 - go.opentelemetry.io/collector/extension/xextension v0.137.0 // indirect
49 - go.opentelemetry.io/collector/featuregate v1.43.0 // indirect
50 - go.opentelemetry.io/collector/internal/telemetry v0.137.0 // indirect
51 - go.opentelemetry.io/collector/pdata/pprofile v0.137.0 // indirect
52 - go.opentelemetry.io/collector/pdata/xpdata v0.137.0 // indirect
53 - go.opentelemetry.io/collector/pipeline v1.43.0 // indirect
54 - go.opentelemetry.io/collector/receiver v1.43.0 // indirect
55 - go.opentelemetry.io/collector/receiver/receivertest v0.137.0 // indirect
56 - go.opentelemetry.io/collector/receiver/xreceiver v0.137.0 // indirect
57 - go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 // indirect
58 - go.opentelemetry.io/otel v1.38.0 // indirect
59 - go.opentelemetry.io/otel/log v0.14.0 // indirect
60 - go.opentelemetry.io/otel/metric v1.38.0 // indirect
61 - go.opentelemetry.io/otel/sdk v1.38.0 // indirect
62 - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
63 - go.opentelemetry.io/otel/trace v1.38.0 // indirect
64 - go.uber.org/multierr v1.11.0 // indirect
65 - go.yaml.in/yaml/v3 v3.0.4 // indirect
66 - golang.org/x/net v0.46.0 // indirect
67 - golang.org/x/sys v0.37.0 // indirect
68 - golang.org/x/text v0.30.0 // indirect
69 - google.golang.org/genproto/googleapis/rpc v0.0.0-20251007200510-49b9836ed3ff // indirect
70 - google.golang.org/grpc v1.76.0 // indirect
71 - google.golang.org/protobuf v1.36.10 // indirect
72 - gopkg.in/yaml.v3 v3.0.1 // indirect
73 -)
src/go/otel-collector/exporter/journaldexporter/go.sum deleted
-191
@@ -1,191 +0,0 @@
1 -github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
2 -github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
3 -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4 -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
5 -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6 -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
7 -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
8 -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
9 -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
10 -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
11 -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
12 -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
13 -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
14 -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
15 -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
16 -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
17 -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
18 -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
19 -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
20 -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
21 -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
22 -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
23 -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
24 -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
25 -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
26 -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
27 -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
28 -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
29 -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
30 -github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo=
31 -github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
32 -github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE=
33 -github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A=
34 -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM=
35 -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28=
36 -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
37 -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
38 -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
39 -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
40 -github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
41 -github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
42 -github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
43 -github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
44 -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
45 -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
46 -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
47 -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
48 -github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
49 -github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
50 -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
51 -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
52 -github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
53 -github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
54 -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
55 -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
56 -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
57 -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
58 -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
59 -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
60 -go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
61 -go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
62 -go.opentelemetry.io/collector/client v1.43.0 h1:uWAjq2AHoKg1Yz4/NKYoDPKhU6jJSSWX9zIKdGLCOlg=
63 -go.opentelemetry.io/collector/client v1.43.0/go.mod h1:9EQOLvyRdozYDKOC7XHIapKT2N6wGWHqgbDply/uRj4=
64 -go.opentelemetry.io/collector/component v1.43.0 h1:9dyOmV0UuIhrNSASMeDH125jhfv7+FhWMq0HtNHHCs8=
65 -go.opentelemetry.io/collector/component v1.43.0/go.mod h1:Pw3qM5HhgnSMpebNRUiiJuEiXxZyHq83vl7wXqxD8hU=
66 -go.opentelemetry.io/collector/component/componenttest v0.137.0 h1:QC9MZsYyzQqN9qMlleJb78wf7FeCjbr4jLeCuNlKHLU=
67 -go.opentelemetry.io/collector/component/componenttest v0.137.0/go.mod h1:JuiX9pv7qE5G8keihhjM66LeidryEnziPND0sXuK9PQ=
68 -go.opentelemetry.io/collector/config/configoptional v1.43.0 h1:u/MCeLUawXINEi05VdRuBRQ3wivEltxTjJqnL1eww4w=
69 -go.opentelemetry.io/collector/config/configoptional v1.43.0/go.mod h1:vdhEmJCpL4nQx2fETr3Bvg9Uy14IwThxL5/g8Mvo/A8=
70 -go.opentelemetry.io/collector/config/configretry v1.43.0 h1:Va5pDNL0TOzqjLdJZ4xxQN9EggMSGVmxXBa+M6UEG30=
71 -go.opentelemetry.io/collector/config/configretry v1.43.0/go.mod h1:ZSTYqAJCq4qf+/4DGoIxCElDIl5yHt8XxEbcnpWBbMM=
72 -go.opentelemetry.io/collector/confmap v1.43.0 h1:QVAnbS7A+2Ra61xsuG355vhlW6uOMaKWysrwLQzDUz4=
73 -go.opentelemetry.io/collector/confmap v1.43.0/go.mod h1:N5GZpFCmwD1GynDu3IWaZW5Ycfc/7YxSU0q1/E3vLdg=
74 -go.opentelemetry.io/collector/confmap/xconfmap v0.137.0 h1:IKzD6w4YuvBi6GvxZfhz7SJR6GR1UpSQRuxtx20/+9U=
75 -go.opentelemetry.io/collector/confmap/xconfmap v0.137.0/go.mod h1:psXdQr13pVrCqNPdoER2QZZorvONAR5ZUEHURe4POh4=
76 -go.opentelemetry.io/collector/consumer v1.43.0 h1:51pfN5h6PLlaBwGPtyHn6BdK0DgtVGRV0UYRPbbscbs=
77 -go.opentelemetry.io/collector/consumer v1.43.0/go.mod h1:v3J2g+6IwOPbLsnzL9cQfvgpmmsZt1YS7aXSNDFmJfk=
78 -go.opentelemetry.io/collector/consumer/consumererror v0.137.0 h1:4HgYX6vVmaF17RRRtJDpR8EuWmLAv6JdKYG8slDDa+g=
79 -go.opentelemetry.io/collector/consumer/consumererror v0.137.0/go.mod h1:muYN3UZ/43YHpDpQRVvCj0Rhpt/YjoPAF/BO63cPSwk=
80 -go.opentelemetry.io/collector/consumer/consumertest v0.137.0 h1:tkqBk/DmJcrkRvHwNdDwvdiWfqyS6ymGgr9eyn6Vy6A=
81 -go.opentelemetry.io/collector/consumer/consumertest v0.137.0/go.mod h1:6bKAlEgrAZ3NSn7ULLFZQMQtlW2xJlvVWkzIaGprucg=
82 -go.opentelemetry.io/collector/consumer/xconsumer v0.137.0 h1:p3tkV3O9bL3bZl3RN2wmoxl22f8B8eMomKUqz656OPY=
83 -go.opentelemetry.io/collector/consumer/xconsumer v0.137.0/go.mod h1:N+nRnP0ga4Scu8Ew87F+kxVajE/eGjRLbWC9H+elN5Q=
84 -go.opentelemetry.io/collector/exporter v1.43.0 h1:FYQ/bhOOiLcmIFvDAUvqfzHmZSvKkTrIFyYprPw3xug=
85 -go.opentelemetry.io/collector/exporter v1.43.0/go.mod h1:lUB2OSGrRyD5PSXU0rF9gWcUYCGublBdnCV5hKlG+z8=
86 -go.opentelemetry.io/collector/exporter/exporterhelper v0.137.0 h1:ffiZjBJvzgPYJpOltwIpvTCF8zg1VPxsoP6aW4VTDuQ=
87 -go.opentelemetry.io/collector/exporter/exporterhelper v0.137.0/go.mod h1:osf2K/HkbdUU7EFigLhxMmz2r5MX/74vYC2RrBDURrc=
88 -go.opentelemetry.io/collector/exporter/exportertest v0.137.0 h1:JesnY7M87UWE/gRsVUgskX95QCL/S4j1ARQTVHH4ggg=
89 -go.opentelemetry.io/collector/exporter/exportertest v0.137.0/go.mod h1:6UxHqO5IyMKL3ehlE3UNpFupIyGc5BBj7xzmPoDImOI=
90 -go.opentelemetry.io/collector/exporter/xexporter v0.137.0 h1:2fSmBDB+tuFoYKJSHbR/1nJIeO+LvvrjdOYEODKuhdo=
91 -go.opentelemetry.io/collector/exporter/xexporter v0.137.0/go.mod h1:9gudRad3ijkbzcnTLE0y+CzUDtC4TaPyZQDUKB2yzVs=
92 -go.opentelemetry.io/collector/extension v1.43.0 h1:39cGAGMJIZEhhm4KbsvJJrG8AheS6wOc++ydY0Wpdp0=
93 -go.opentelemetry.io/collector/extension v1.43.0/go.mod h1:HVCPnRqx70Qn9BAmnqJt393er4l1OwcgAytLv1fSOSo=
94 -go.opentelemetry.io/collector/extension/extensiontest v0.137.0 h1:gnPF3HIOKqNk93XObt2x0WFvVfPtm76VggWe7LxgcaY=
95 -go.opentelemetry.io/collector/extension/extensiontest v0.137.0/go.mod h1:vVmKojdITYka9+iAi3aarxeMrO6kdlywKuf3d3c6lcI=
96 -go.opentelemetry.io/collector/extension/xextension v0.137.0 h1:UQ/I7D5/YmkvAV7g8yhWHY7BV31HvjGBCYduQJPyt+M=
97 -go.opentelemetry.io/collector/extension/xextension v0.137.0/go.mod h1:T2Vr5ijSNW7PavuyZyRYYxCitpUTN+f4tRUdED/rtRw=
98 -go.opentelemetry.io/collector/featuregate v1.43.0 h1:Aq8UR5qv1zNlbbkTyqv8kLJtnoQMq/sG1/jS9o1cCJI=
99 -go.opentelemetry.io/collector/featuregate v1.43.0/go.mod h1:d0tiRzVYrytB6LkcYgz2ESFTv7OktRPQe0QEQcPt1L4=
100 -go.opentelemetry.io/collector/internal/telemetry v0.137.0 h1:KlJcaBnIIn+QJzQIfA1eXbYUvHmgM7h/gLp/vjvUBMw=
101 -go.opentelemetry.io/collector/internal/telemetry v0.137.0/go.mod h1:GWOiXBZ82kMzwGMEihJ5rEo5lFL7gurfHD++5q0XtI8=
102 -go.opentelemetry.io/collector/pdata v1.43.0 h1:zVkj2hcjiMLwX+QDDNwb7iTh3LBjNXKv2qPSgj1Rzb4=
103 -go.opentelemetry.io/collector/pdata v1.43.0/go.mod h1:KsJzdDG9e5BaHlmYr0sqdSEKeEiSfKzoF+rdWU7J//w=
104 -go.opentelemetry.io/collector/pdata/pprofile v0.137.0 h1:bLVp8p8hpH81eQhhEQBkvLtS00GbnMU+ItNweBJLqZ8=
105 -go.opentelemetry.io/collector/pdata/pprofile v0.137.0/go.mod h1:QfhMf7NnG+fTuwGGB1mXgcPzcXNxEYSW6CrVouOsF7Q=
106 -go.opentelemetry.io/collector/pdata/testdata v0.137.0 h1:+oaGvbt0v7xryTX827szmyYWSAtvA0LbysEFV2nFjs0=
107 -go.opentelemetry.io/collector/pdata/testdata v0.137.0/go.mod h1:3512FJaQsZz5EBlrY46xKjzoBc0MoMcQtAqYs2NaRQM=
108 -go.opentelemetry.io/collector/pdata/xpdata v0.137.0 h1:EZvBE26Hxzk+Dv3NU7idjsS+cXbwZrwdWXGgcTxsC8g=
109 -go.opentelemetry.io/collector/pdata/xpdata v0.137.0/go.mod h1:MFbISBnECZ1m1JPc5F6LUhVIkmFkebuVk3NcpmGPtB8=
110 -go.opentelemetry.io/collector/pipeline v1.43.0 h1:IJjdqE5UCQlyVvFUUzlhSWhP4WIwpH6UyJQ9iWXpyww=
111 -go.opentelemetry.io/collector/pipeline v1.43.0/go.mod h1:xUrAqiebzYbrgxyoXSkk6/Y3oi5Sy3im2iCA51LwUAI=
112 -go.opentelemetry.io/collector/receiver v1.43.0 h1:Z/+es1SFKCwgd7mPy3Jf5KUSgy7WyypSExg4NshOwaY=
113 -go.opentelemetry.io/collector/receiver v1.43.0/go.mod h1:XhP5zl+MOMbqvvc9I5JjwULIzp7dRRUxo53EHmrl5Bc=
114 -go.opentelemetry.io/collector/receiver/receivertest v0.137.0 h1:LqlFKtThf07dFjYGLMfI2J4aio60S03gocm8CL6jOd4=
115 -go.opentelemetry.io/collector/receiver/receivertest v0.137.0/go.mod h1:bg4wfd9uq3jZfarMcqanHhQDlwbByp3GHCY7I6YO/QY=
116 -go.opentelemetry.io/collector/receiver/xreceiver v0.137.0 h1:30h6o1hI03PSc0upgwWMFRZYaVrqLaruA6r/jI1Kk/4=
117 -go.opentelemetry.io/collector/receiver/xreceiver v0.137.0/go.mod h1:kvydfp3S8PKBVXH5OgPsTSneXQ92HGyi30hSrKy1fe4=
118 -go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 h1:aBKdhLVieqvwWe9A79UHI/0vgp2t/s2euY8X59pGRlw=
119 -go.opentelemetry.io/contrib/bridges/otelzap v0.13.0/go.mod h1:SYqtxLQE7iINgh6WFuVi2AI70148B8EI35DSk0Wr8m4=
120 -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
121 -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
122 -go.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM=
123 -go.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno=
124 -go.opentelemetry.io/otel/log/logtest v0.14.0 h1:BGTqNeluJDK2uIHAY8lRqxjVAYfqgcaTbVk1n3MWe5A=
125 -go.opentelemetry.io/otel/log/logtest v0.14.0/go.mod h1:IuguGt8XVP4XA4d2oEEDMVDBBCesMg8/tSGWDjuKfoA=
126 -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
127 -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
128 -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
129 -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
130 -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
131 -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
132 -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
133 -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
134 -go.opentelemetry.io/proto/slim/otlp v1.8.0 h1:afcLwp2XOeCbGrjufT1qWyruFt+6C9g5SOuymrSPUXQ=
135 -go.opentelemetry.io/proto/slim/otlp v1.8.0/go.mod h1:Yaa5fjYm1SMCq0hG0x/87wV1MP9H5xDuG/1+AhvBcsI=
136 -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.1.0 h1:Uc+elixz922LHx5colXGi1ORbsW8DTIGM+gg+D9V7HE=
137 -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.1.0/go.mod h1:VyU6dTWBWv6h9w/+DYgSZAPMabWbPTFTuxp25sM8+s0=
138 -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.1.0 h1:i8YpvWGm/Uq1koL//bnbJ/26eV3OrKWm09+rDYo7keU=
139 -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.1.0/go.mod h1:pQ70xHY/ZVxNUBPn+qUWPl8nwai87eWdqL3M37lNi9A=
140 -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
141 -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
142 -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
143 -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
144 -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
145 -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
146 -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
147 -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
148 -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
149 -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
150 -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
151 -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
152 -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
153 -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
154 -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
155 -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
156 -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
157 -golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
158 -golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
159 -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
160 -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
161 -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
162 -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
163 -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
164 -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
165 -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
166 -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
167 -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
168 -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
169 -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
170 -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
171 -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
172 -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
173 -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
174 -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
175 -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
176 -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
177 -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
178 -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
179 -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
180 -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
181 -google.golang.org/genproto/googleapis/rpc v0.0.0-20251007200510-49b9836ed3ff h1:A90eA31Wq6HOMIQlLfzFwzqGKBTuaVztYu/g8sn+8Zc=
182 -google.golang.org/genproto/googleapis/rpc v0.0.0-20251007200510-49b9836ed3ff/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
183 -google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
184 -google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
185 -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
186 -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
187 -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
188 -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
189 -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
190 -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
191 -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
src/go/otel-collector/exporter/journaldexporter/internal/metadata/generated_status.go deleted
-16
@@ -1,16 +0,0 @@
1 -// Code generated by mdatagen. DO NOT EDIT.
2 -
3 -package metadata
4 -
5 -import (
6 - "go.opentelemetry.io/collector/component"
7 -)
8 -
9 -var (
10 - Type = component.MustNewType("journaldexporter")
11 - ScopeName = "github.com/netdata/netdata/otel-collector/exporter/journaldexporter"
12 -)
13 -
14 -const (
15 - LogsStability = component.StabilityLevelDevelopment
16 -)
src/go/otel-collector/exporter/journaldexporter/journal_remote.go deleted
-287
@@ -1,287 +0,0 @@
1 -package journaldexporter
2 -
3 -import (
4 - "context"
5 - "crypto/tls"
6 - "crypto/x509"
7 - "errors"
8 - "fmt"
9 - "io"
10 - "net"
11 - "net/http"
12 - "os"
13 - "sync"
14 -
15 - "go.uber.org/zap"
16 -)
17 -
18 -func newRemoteJournalClient(cfg *Config) (*remoteJournalClient, error) {
19 - client, err := newHTTPClient(cfg)
20 - if err != nil {
21 - return nil, fmt.Errorf("failed to create remote journal http client: %v", err)
22 - }
23 - return &remoteJournalClient{
24 - remoteURL: cfg.URL,
25 - httpClient: client,
26 - done: make(chan struct{}),
27 - }, nil
28 -}
29 -
30 -type remoteJournalClient struct {
31 - log *zap.Logger
32 -
33 - remoteURL string
34 - httpClient *http.Client
35 -
36 - mu sync.Mutex // Protects access to writer, error info, cancel func
37 - w io.WriteCloser // The pipe writer for the current active upload stream
38 - reqErr error // Stores the error from the last background upload attempt
39 - reqCancel context.CancelFunc // Function to cancel the current background HTTP request
40 -
41 - done chan struct{} // Closed when the httpClient is shutting down
42 - wg sync.WaitGroup // Waits for background operations to complete during done
43 -}
44 -
45 -func (jc *remoteJournalClient) sendMessage(ctx context.Context, msg []byte) error {
46 - if len(msg) == 0 {
47 - return nil
48 - }
49 -
50 - var currentWriter io.WriteCloser
51 - var connectErr error
52 -
53 - jc.mu.Lock()
54 -
55 - select {
56 - case <-ctx.Done():
57 - jc.mu.Unlock()
58 - return ctx.Err()
59 - case <-jc.done:
60 - jc.mu.Unlock()
61 - return errors.New("journal: client is shut down")
62 - default:
63 - }
64 -
65 - if jc.w == nil {
66 - jc.log.Info("journal: not connected, attempting to connect...")
67 - connectErr = jc.connectLocked(ctx)
68 - }
69 -
70 - if connectErr == nil && jc.w != nil {
71 - currentWriter = jc.w
72 - }
73 - lastReqErr := jc.reqErr
74 - jc.mu.Unlock()
75 -
76 - if connectErr != nil {
77 - return fmt.Errorf("journal: connection attempt failed: %w", connectErr)
78 - }
79 -
80 - if currentWriter == nil {
81 - errMsg := "journal: connection unavailable"
82 - if lastReqErr != nil {
83 - return fmt.Errorf("%s (last background error: %w)", errMsg, lastReqErr)
84 - }
85 - return errors.New(errMsg)
86 - }
87 -
88 - if _, err := currentWriter.Write(msg); err != nil {
89 - return fmt.Errorf("journal: failed to write message (connection likely closed): %w", err)
90 - }
91 -
92 - return nil
93 -}
94 -
95 -// connectLocked initiates a new upload stream. Must be called with jc.mu held.
96 -func (jc *remoteJournalClient) connectLocked(ctx context.Context) error {
97 - if jc.w != nil {
98 - jc.log.Warn("journal: warning - connectLocked called while already connected")
99 - jc.disconnectLocked()
100 - }
101 -
102 - if jc.isDone() {
103 - return errors.New("journal: client is shut down")
104 - }
105 -
106 - reqCtx, cancel := context.WithCancel(ctx)
107 - jc.reqCancel = cancel
108 -
109 - pr, pw := io.Pipe()
110 - jc.w = pw
111 - jc.reqErr = nil
112 -
113 - jc.wg.Add(1)
114 - go func() {
115 - defer jc.wg.Done()
116 -
117 - // blocks until the stream finishes.
118 - reqErr := jc.doRequest(reqCtx, pr)
119 -
120 - jc.mu.Lock()
121 - if jc.w == pw {
122 - jc.reqErr = reqErr
123 - jc.w = nil
124 - jc.reqCancel = nil
125 - }
126 - jc.mu.Unlock()
127 -
128 - if reqErr != nil {
129 - if errors.Is(reqErr, context.Canceled) || errors.Is(reqErr, io.ErrClosedPipe) {
130 - jc.log.Info("journal: background upload finished successfully.")
131 - } else {
132 - jc.log.Error("journal: background upload failed with error", zap.Error(reqErr))
133 - }
134 - }
135 - }()
136 -
137 - jc.log.Info("journal: connection attempt initiated (running in background)")
138 -
139 - return nil
140 -}
141 -
142 -func (jc *remoteJournalClient) doRequest(ctx context.Context, pr *io.PipeReader) (err error) {
143 - defer func() { _ = pr.CloseWithError(err) }()
144 -
145 - req, err := http.NewRequestWithContext(ctx, http.MethodPost, jc.remoteURL, pr)
146 - if err != nil {
147 - return fmt.Errorf("could not create request: %w", err)
148 - }
149 -
150 - req.Header.Set("Content-Type", "application/vnd.fdo.journal")
151 -
152 - // This call blocks until the request body (pr) is closed, the context is canceled,
153 - // the server responds AND closes the connection, or a connection error occurs.
154 - resp, err := jc.httpClient.Do(req)
155 - if err != nil {
156 - if errors.Is(err, context.Canceled) {
157 - jc.log.Info("journal: request cancelled via context.")
158 - } else {
159 - jc.log.Warn(fmt.Sprintf("journal: http client error: %v", err))
160 - }
161 - return err
162 - }
163 -
164 - defer closeBody(resp)
165 -
166 - if resp.StatusCode < 200 || resp.StatusCode >= 300 {
167 - bodyBytes, _ := io.ReadAll(resp.Body)
168 - return fmt.Errorf("unexpected status code %d: %s", resp.StatusCode, string(bodyBytes))
169 - }
170 -
171 - return nil
172 -}
173 -
174 -func (jc *remoteJournalClient) shutdown(ctx context.Context) error {
175 - jc.mu.Lock()
176 - if jc.isDone() {
177 - jc.mu.Unlock()
178 - jc.log.Warn("journal: client is shut down")
179 - return nil
180 - }
181 -
182 - close(jc.done)
183 - jc.log.Info("journal: shutdown initiated.")
184 - jc.disconnectLocked()
185 -
186 - jc.mu.Unlock()
187 -
188 - done := make(chan struct{})
189 - go func() {
190 - jc.wg.Wait()
191 - close(done)
192 - }()
193 -
194 - select {
195 - case <-done:
196 - jc.log.Info("journal: all background tasks finished.")
197 - return nil
198 - case <-ctx.Done():
199 - jc.log.Info("journal: shutdown timed out waiting for background tasks.")
200 - return ctx.Err()
201 - }
202 -}
203 -
204 -// disconnectLocked cancels the current request and closes the writer pipe. Must be called with jc.mu held.
205 -func (jc *remoteJournalClient) disconnectLocked() {
206 - if jc.w != nil {
207 - _ = jc.w.Close()
208 - jc.w = nil
209 - }
210 - if jc.reqCancel != nil {
211 - jc.reqCancel()
212 - jc.reqCancel = nil
213 - }
214 -}
215 -
216 -func (jc *remoteJournalClient) isDone() bool {
217 - select {
218 - case <-jc.done:
219 - return true
220 - default:
221 - return false
222 - }
223 -}
224 -
225 -func newHTTPClient(cfg *Config) (*http.Client, error) {
226 - tlsConfig, err := newTLSConfig(cfg)
227 - if err != nil {
228 - return nil, err
229 - }
230 -
231 - d := &net.Dialer{Timeout: cfg.Timeout}
232 -
233 - client := http.Client{
234 - Timeout: cfg.Timeout,
235 - Transport: &http.Transport{
236 - TLSClientConfig: tlsConfig,
237 - DialContext: d.DialContext,
238 - TLSHandshakeTimeout: cfg.Timeout,
239 - },
240 - }
241 -
242 - return &client, nil
243 -}
244 -
245 -func newTLSConfig(cfg *Config) (*tls.Config, error) {
246 - if cfg.TLS.SrvCertFile == "" && cfg.TLS.SrvKeyFile == "" && cfg.TLS.TrustedCertFile == "" && !cfg.TLS.InsecureSkipVerify {
247 - return nil, nil
248 - }
249 -
250 - var clientCerts []tls.Certificate
251 - if cfg.TLS.SrvCertFile != "" && cfg.TLS.SrvKeyFile != "" {
252 - clientCert, err := tls.LoadX509KeyPair(cfg.TLS.SrvCertFile, cfg.TLS.SrvKeyFile)
253 - if err != nil {
254 - return nil, fmt.Errorf("error loading tls cert and key files: %s", err)
255 - }
256 - clientCerts = append(clientCerts, clientCert)
257 - }
258 -
259 - tlsConfig := &tls.Config{
260 - Certificates: clientCerts,
261 - MinVersion: tls.VersionTLS12,
262 - }
263 -
264 - if cfg.TLS.TrustedCertFile != "" {
265 - caCert, err := os.ReadFile(cfg.TLS.TrustedCertFile)
266 - if err != nil {
267 - return nil, fmt.Errorf("failed to read CA certificate file %q: %w", cfg.TLS.TrustedCertFile, err)
268 - }
269 - caCertPool := x509.NewCertPool()
270 - if !caCertPool.AppendCertsFromPEM(caCert) {
271 - return nil, fmt.Errorf("failed to append CA certificate from %q", cfg.TLS.TrustedCertFile)
272 - }
273 - tlsConfig.RootCAs = caCertPool
274 - tlsConfig.InsecureSkipVerify = false
275 - } else if cfg.TLS.InsecureSkipVerify {
276 - tlsConfig.InsecureSkipVerify = true
277 - }
278 -
279 - return tlsConfig, nil
280 -}
281 -
282 -func closeBody(resp *http.Response) {
283 - if resp != nil && resp.Body != nil {
284 - _, _ = io.Copy(io.Discard, resp.Body)
285 - _ = resp.Body.Close()
286 - }
287 -}
src/go/otel-collector/exporter/journaldexporter/journal_remote_test.go deleted
-435
@@ -1,435 +0,0 @@
1 -package journaldexporter
2 -
3 -import (
4 - "bytes"
5 - "context"
6 - "errors"
7 - "fmt"
8 - "io"
9 - "net/http"
10 - "net/http/httptest"
11 - "strings"
12 - "sync"
13 - "testing"
14 - "time"
15 -
16 - "github.com/stretchr/testify/assert"
17 - "github.com/stretchr/testify/require"
18 - "go.uber.org/zap"
19 - "go.uber.org/zap/zaptest"
20 -)
21 -
22 -func TestRemoteJournalClient_sendMessage(t *testing.T) {
23 - tests := map[string]struct {
24 - prepare func(t *testing.T) (*httptest.Server, *chunkReaderTestHandler)
25 - messages []string
26 - wantErr bool
27 - }{
28 - "successful message delivery": {
29 - prepare: func(t *testing.T) (*httptest.Server, *chunkReaderTestHandler) {
30 - return prepareTestServer(t)
31 - },
32 - messages: []string{
33 - `{"message":"hello world1"}`,
34 - `{"message":"hello world2"}`,
35 - `{"message":"hello world3"}`,
36 - },
37 - },
38 - "error message delivery": {
39 - wantErr: true,
40 - prepare: func(t *testing.T) (*httptest.Server, *chunkReaderTestHandler) {
41 - srv, h := prepareTestServer(t)
42 - h.errorAfterRead = true
43 - return srv, h
44 - },
45 - messages: []string{
46 - `{"message":"hello world1"}`,
47 - `{"message":"hello world2"}`,
48 - `{"message":"hello world3"}`,
49 - },
50 - },
51 - "connection abrupt close": {
52 - wantErr: true,
53 - prepare: func(t *testing.T) (*httptest.Server, *chunkReaderTestHandler) {
54 - srv, h := prepareTestServer(t)
55 - h.closeEarly = true
56 - return srv, h
57 - },
58 - messages: []string{
59 - `{"message":"hello world1"}`,
60 - `{"message":"hello world2"}`,
61 - },
62 - },
63 - "attempt to send to non-existent server": {
64 - wantErr: true,
65 - prepare: func(t *testing.T) (*httptest.Server, *chunkReaderTestHandler) {
66 - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
67 - srv.Close()
68 -
69 - return srv, nil
70 - },
71 - messages: []string{
72 - `{"message":"hello world1"}`,
73 - },
74 - },
75 - "empty message": {
76 - prepare: func(t *testing.T) (*httptest.Server, *chunkReaderTestHandler) {
77 - return prepareTestServer(t)
78 - },
79 - messages: []string{
80 - ``,
81 - },
82 - },
83 - "large message": {
84 - prepare: func(t *testing.T) (*httptest.Server, *chunkReaderTestHandler) {
85 - return prepareTestServer(t)
86 - },
87 - messages: []string{
88 - strings.Repeat(`{"message":"large payload test"}`, 1000),
89 - },
90 - },
91 - "slow server response": {
92 - prepare: func(t *testing.T) (*httptest.Server, *chunkReaderTestHandler) {
93 - srv, h := prepareTestServer(t)
94 - h.readDelay = 200 * time.Millisecond
95 - return srv, h
96 - },
97 - messages: []string{
98 - `{"message":"hello world1"}`,
99 - `{"message":"hello world2"}`,
100 - },
101 - },
102 - }
103 -
104 - for name, test := range tests {
105 - t.Run(name, func(t *testing.T) {
106 - srv, h := test.prepare(t)
107 - if srv != nil {
108 - defer srv.Close()
109 - }
110 -
111 - jc := prepareRemoteJournalClient(t, srv.URL)
112 -
113 - var wg sync.WaitGroup
114 - sendErrCh := make(chan error, 1)
115 - recvErrCh := make(chan error, 1)
116 -
117 - // Skip receive handling for non-existent server and empty message cases
118 - skipReceive := h == nil || len(test.messages) == 0 ||
119 - (len(test.messages) == 1 && test.messages[0] == "")
120 -
121 - wg.Add(1)
122 - go func() {
123 - defer wg.Done()
124 - var err error
125 - for _, msg := range test.messages {
126 - err = errors.Join(err, jc.sendMessage(context.Background(), []byte(msg)))
127 - // Brief pause to allow processing
128 - time.Sleep(50 * time.Millisecond)
129 - }
130 - sendErrCh <- err
131 - }()
132 -
133 - if skipReceive {
134 - // For non-server or empty message tests, we don't expect to receive anything
135 - recvErrCh <- nil
136 - } else {
137 - wg.Add(1)
138 - go func() {
139 - defer wg.Done()
140 -
141 - want := strings.Join(test.messages, "")
142 - var buf bytes.Buffer
143 - timeout := 5 * time.Second
144 -
145 - // For large payloads, extend timeout
146 - if len(want) > 10000 {
147 - timeout = 10 * time.Second
148 - }
149 -
150 - timeoutCh := time.After(timeout)
151 -
152 - for {
153 - select {
154 - case msg, ok := <-h.recDataCh:
155 - if !ok {
156 - // If we're expecting an error due to connection close,
157 - // this is normal and not a test failure
158 - if test.wantErr && buf.Len() > 0 {
159 - recvErrCh <- nil
160 - } else if buf.String() == want {
161 - recvErrCh <- nil
162 - } else if buf.Len() > 0 {
163 - recvErrCh <- fmt.Errorf("received incomplete data: got %q, want %q",
164 - buf.String(), want)
165 - } else {
166 - recvErrCh <- errors.New("channel closed without receiving data")
167 - }
168 - return
169 - }
170 - _, _ = buf.Write(bytes.Clone(msg))
171 - if buf.String() == want {
172 - recvErrCh <- nil
173 - return
174 - }
175 - case <-timeoutCh:
176 - recvErrCh <- fmt.Errorf("timeout waiting for messages after %v", timeout)
177 - return
178 - }
179 - }
180 - }()
181 - }
182 -
183 - done := make(chan struct{})
184 - go func() {
185 - defer close(done)
186 - wg.Wait()
187 - }()
188 -
189 - select {
190 - case <-done:
191 - case <-time.After(10 * time.Second):
192 - _ = jc.shutdown(context.Background())
193 - t.Fatal("timed out waiting for test completion")
194 - }
195 -
196 - shutdownCtx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
197 - defer cancel()
198 - err := jc.shutdown(shutdownCtx)
199 - if err != nil {
200 - t.Logf("Shutdown error (non-fatal): %v", err)
201 - }
202 -
203 - // Give the test a moment to complete any pending operations
204 - time.Sleep(100 * time.Millisecond)
205 -
206 - var sendErr, recvErr error
207 - select {
208 - case sendErr = <-sendErrCh:
209 - default:
210 - sendErr = errors.New("send goroutine did not complete")
211 - }
212 -
213 - if !skipReceive {
214 - select {
215 - case recvErr = <-recvErrCh:
216 - default:
217 - recvErr = errors.New("receive goroutine did not complete")
218 - }
219 - }
220 -
221 - combinedErr := errors.Join(sendErr, recvErr)
222 -
223 - if test.wantErr {
224 - if name == "empty message" {
225 - // Empty message should not cause an error
226 - assert.NoError(t, combinedErr, "empty message should not cause error")
227 - } else {
228 - assert.Error(t, combinedErr, "expected an error but got none")
229 - }
230 - } else {
231 - assert.NoError(t, combinedErr, "unexpected error")
232 - }
233 - })
234 - }
235 -}
236 -
237 -func TestRemoteJournalClient_ConcurrentMessages(t *testing.T) {
238 - srv, h := prepareTestServer(t)
239 - defer srv.Close()
240 -
241 - jc := prepareRemoteJournalClient(t, srv.URL)
242 -
243 - const numMessages = 10
244 - const numGoroutines = 5
245 -
246 - var wg sync.WaitGroup
247 - for i := 0; i < numGoroutines; i++ {
248 - wg.Add(1)
249 - go func(id int) {
250 - defer wg.Done()
251 - for j := 0; j < numMessages; j++ {
252 - msg := fmt.Sprintf(`{"goroutine":%d,"message":%d}`, id, j)
253 - err := jc.sendMessage(context.Background(), []byte(msg))
254 - if err != nil {
255 - t.Errorf("Error sending message from goroutine %d: %v", id, err)
256 - return
257 - }
258 - // Small delay to interleave messages
259 - time.Sleep(10 * time.Millisecond)
260 - }
261 - }(i)
262 - }
263 -
264 - received := make([]string, 0, numMessages*numGoroutines)
265 - receiveDone := make(chan struct{})
266 -
267 - go func() {
268 - defer close(receiveDone)
269 - for {
270 - select {
271 - case msg, ok := <-h.recDataCh:
272 - if !ok {
273 - return
274 - }
275 - received = append(received, string(msg))
276 - case <-time.After(5 * time.Second):
277 - t.Error("Timeout waiting for messages")
278 - return
279 - }
280 - }
281 - }()
282 -
283 - wg.Wait()
284 -
285 - err := jc.shutdown(context.Background())
286 - require.NoError(t, err)
287 -
288 - select {
289 - case <-receiveDone:
290 - case <-time.After(2 * time.Second):
291 - t.Fatal("Timeout waiting for receiver to complete")
292 - }
293 -
294 - t.Logf("Received %d message chunks", len(received))
295 - fullMessage := strings.Join(received, "")
296 -
297 - messageCount := strings.Count(fullMessage, `{"goroutine":`)
298 - assert.GreaterOrEqual(t, messageCount, numMessages*numGoroutines,
299 - "Did not receive all expected messages")
300 -}
301 -
302 -func TestRemoteJournalClient_ContextCancellation(t *testing.T) {
303 - srv, _ := prepareTestServer(t)
304 - defer srv.Close()
305 -
306 - jc := prepareRemoteJournalClient(t, srv.URL)
307 -
308 - ctx, cancel := context.WithCancel(context.Background())
309 -
310 - cancel()
311 -
312 - err := jc.sendMessage(ctx, []byte(`{"message":"should not be sent"}`))
313 - assert.Error(t, err, "Expected error due to cancelled context")
314 - assert.ErrorIs(t, err, context.Canceled, "Error should be context.Canceled")
315 -
316 - _ = jc.shutdown(context.Background())
317 -}
318 -
319 -func TestRemoteJournalClient_SendAfterShutdown(t *testing.T) {
320 - srv, _ := prepareTestServer(t)
321 - defer srv.Close()
322 -
323 - jc := prepareRemoteJournalClient(t, srv.URL)
324 -
325 - err := jc.shutdown(context.Background())
326 - require.NoError(t, err, "Shutdown should succeed")
327 -
328 - err = jc.sendMessage(context.Background(), []byte(`{"message":"after shutdown"}`))
329 - assert.Error(t, err, "Expected error when sending to shut down client")
330 - assert.Contains(t, err.Error(), "client is shut down",
331 - "Error should indicate client is shut down")
332 -}
333 -
334 -type chunkReaderTestHandler struct {
335 - log *zap.Logger
336 - recDataCh chan []byte
337 - readDelay time.Duration // Delay between reads (simulates slow processing)
338 - errorAfterRead bool // If true, send an error status *after* reading at least one chunk
339 - closeEarly bool // If true, simulate an abrupt connection close *after* reading at least one chunk
340 -}
341 -
342 -func newChunkReaderTestHandler(t *testing.T) *chunkReaderTestHandler {
343 - return &chunkReaderTestHandler{
344 - log: zaptest.NewLogger(t),
345 - recDataCh: make(chan []byte),
346 - }
347 -}
348 -
349 -func (h *chunkReaderTestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
350 - defer func() {
351 - close(h.recDataCh)
352 - }()
353 -
354 - contentType := r.Header.Get("Content-Type")
355 - if contentType != "application/vnd.fdo.journal" {
356 - h.log.Error("Received invalid content type", zap.String("content-type", contentType))
357 - http.Error(w, "Invalid content type", http.StatusBadRequest)
358 - return
359 - }
360 -
361 - buf := make([]byte, 1024)
362 -
363 - for {
364 - if h.readDelay > 0 {
365 - time.Sleep(h.readDelay)
366 - }
367 -
368 - n, err := r.Body.Read(buf)
369 - if err != nil {
370 - if err == io.EOF {
371 - h.log.Info("Finished reading request body (EOF)")
372 - break
373 - }
374 - h.log.Error("Error reading request body", zap.Error(err))
375 - http.Error(w, fmt.Sprintf("Error reading request body: %v", err), http.StatusInternalServerError)
376 - return
377 - }
378 -
379 - if h.errorAfterRead {
380 - h.log.Info("Simulating error response after read")
381 - http.Error(w, "Simulated processing error after read", http.StatusInternalServerError)
382 - return
383 - }
384 -
385 - if h.closeEarly {
386 - h.log.Info("Simulating connection abrupt close")
387 - hj, ok := w.(http.Hijacker)
388 - if !ok {
389 - h.log.Warn("Cannot simulate close early: Hijacking not supported")
390 - http.Error(w, "Cannot simulate early close (hijacking not supported)", http.StatusInternalServerError)
391 - return
392 - }
393 - conn, _, _ := hj.Hijack()
394 - _ = conn.Close()
395 - fmt.Println("Connection closed abruptly.")
396 - return
397 - }
398 -
399 - select {
400 - case h.recDataCh <- bytes.Clone(buf[:n]):
401 - case <-time.After(time.Second * 5):
402 - http.Error(w, "Sending read data back timed out", http.StatusLocked)
403 - return
404 - }
405 - }
406 -
407 - _, _ = io.Copy(io.Discard, r.Body)
408 - _ = r.Body.Close()
409 - w.WriteHeader(http.StatusOK)
410 -}
411 -
412 -func prepareTestServer(t *testing.T) (*httptest.Server, *chunkReaderTestHandler) {
413 - handler := newChunkReaderTestHandler(t)
414 -
415 - server := httptest.NewServer(handler)
416 - t.Cleanup(func() {
417 - server.Close()
418 - })
419 - return server, handler
420 -}
421 -
422 -func prepareRemoteJournalClient(t *testing.T, serverURL string) *remoteJournalClient {
423 - cfg := &Config{
424 - URL: serverURL,
425 - Timeout: 3 * time.Second,
426 - }
427 -
428 - client, err := newRemoteJournalClient(cfg)
429 - require.NoError(t, err)
430 - require.NotNil(t, client)
431 -
432 - client.log = zaptest.NewLogger(t)
433 -
434 - return client
435 -}
src/go/otel-collector/exporter/journaldexporter/journal_socket.go deleted
-190
@@ -1,190 +0,0 @@
1 -package journaldexporter
2 -
3 -import (
4 - "context"
5 - "errors"
6 - "fmt"
7 - "net"
8 - "os"
9 - "sync"
10 - "syscall"
11 - "time"
12 -)
13 -
14 -const defaultJournalSocket = "/run/systemd/journal/socket"
15 -
16 -func newSocketJournalClient() (*socketJournalClient, error) {
17 - if _, err := os.Stat(defaultJournalSocket); os.IsNotExist(err) {
18 - return nil, fmt.Errorf("journal socket does not exist: %w", err)
19 - }
20 -
21 - conn, err := createJournalConn()
22 - if err != nil {
23 - return nil, fmt.Errorf("failed to create journal connection: %w", err)
24 - }
25 -
26 - tempFile, err := createUnlinkedTempFile()
27 - if err != nil {
28 - _ = conn.Close()
29 - return nil, fmt.Errorf("failed to create temporary file: %w", err)
30 - }
31 -
32 - return &socketJournalClient{
33 - socketPath: defaultJournalSocket,
34 - conn: conn,
35 - done: make(chan struct{}),
36 - tempFile: tempFile,
37 - }, nil
38 -}
39 -
40 -type socketJournalClient struct {
41 - socketPath string
42 - conn *net.UnixConn
43 - mu sync.Mutex
44 - done chan struct{}
45 -
46 - // Pre-created temporary file for large messages
47 - tempFile *os.File
48 -}
49 -
50 -func (jc *socketJournalClient) sendMessage(ctx context.Context, msg []byte) error {
51 - if len(msg) == 0 {
52 - return nil
53 - }
54 - if jc.conn == nil {
55 - return errors.New("journal: connection is closed")
56 - }
57 -
58 - jc.mu.Lock()
59 - defer jc.mu.Unlock()
60 -
61 - select {
62 - case <-ctx.Done():
63 - return ctx.Err()
64 - case <-jc.done:
65 - return errors.New("journal: client is shut down")
66 - default:
67 - }
68 -
69 - socketAddr := &net.UnixAddr{
70 - Name: jc.socketPath,
71 - Net: "unixgram",
72 - }
73 -
74 - if err := jc.setConnWriteDeadline(ctx); err != nil {
75 - return fmt.Errorf("journal: failed to set write deadline: %w", err)
76 - }
77 -
78 - if _, _, err := jc.conn.WriteMsgUnix(msg, nil, socketAddr); err != nil {
79 - if !isSocketSpaceError(err) {
80 - return fmt.Errorf("journal: failed to write to socket: %w", err)
81 - }
82 - return jc.sendViaFd(ctx, msg, socketAddr)
83 - }
84 -
85 - return nil
86 -}
87 -
88 -func (jc *socketJournalClient) sendViaFd(ctx context.Context, msg []byte, socketAddr *net.UnixAddr) error {
89 - if _, err := jc.tempFile.Seek(0, 0); err != nil {
90 - return fmt.Errorf("journal: failed to seek in temporary file: %w", err)
91 - }
92 -
93 - if err := jc.tempFile.Truncate(0); err != nil {
94 - return fmt.Errorf("journal: failed to truncate temporary file: %w", err)
95 - }
96 -
97 - if _, err := jc.tempFile.Write(msg); err != nil {
98 - return fmt.Errorf("journal: failed to write to temporary file: %w", err)
99 - }
100 -
101 - if _, err := jc.tempFile.Seek(0, 0); err != nil {
102 - return fmt.Errorf("journal: failed to reset file position: %w", err)
103 - }
104 -
105 - rights := syscall.UnixRights(int(jc.tempFile.Fd()))
106 -
107 - if err := jc.setConnWriteDeadline(ctx); err != nil {
108 - return fmt.Errorf("journal: failed to set write deadline: %w", err)
109 - }
110 -
111 - if _, _, err := jc.conn.WriteMsgUnix([]byte{}, rights, socketAddr); err != nil {
112 - return fmt.Errorf("journal: failed to send file descriptor: %w", err)
113 - }
114 -
115 - return nil
116 -}
117 -
118 -func (jc *socketJournalClient) shutdown(ctx context.Context) error {
119 - jc.mu.Lock()
120 - defer jc.mu.Unlock()
121 -
122 - select {
123 - case <-jc.done:
124 - return nil
125 - default:
126 - close(jc.done)
127 - }
128 -
129 - if jc.tempFile != nil {
130 - _ = jc.tempFile.Close()
131 - jc.tempFile = nil
132 - }
133 -
134 - if jc.conn != nil {
135 - _ = jc.conn.Close()
136 - jc.conn = nil
137 - }
138 -
139 - return nil
140 -}
141 -
142 -func (jc *socketJournalClient) setConnWriteDeadline(ctx context.Context) error {
143 - var timeout = 5 * time.Second
144 - if deadline, ok := ctx.Deadline(); ok {
145 - timeout = time.Until(deadline)
146 - }
147 - return jc.conn.SetWriteDeadline(time.Now().Add(timeout))
148 -}
149 -
150 -func createJournalConn() (*net.UnixConn, error) {
151 - autobind, err := net.ResolveUnixAddr("unixgram", "")
152 - if err != nil {
153 - return nil, fmt.Errorf("failed to resolve unix address: %w", err)
154 - }
155 -
156 - conn, err := net.ListenUnixgram("unixgram", autobind)
157 - if err != nil {
158 - return nil, fmt.Errorf("failed to create unix datagram socket: %w", err)
159 - }
160 -
161 - return conn, nil
162 -}
163 -
164 -func createUnlinkedTempFile() (*os.File, error) {
165 - file, err := os.CreateTemp("/dev/shm/", "journal.XXXXX")
166 - if err != nil {
167 - return nil, err
168 - }
169 -
170 - // Unlink the file so it's automatically cleaned up when closed
171 - err = syscall.Unlink(file.Name())
172 - if err != nil {
173 - _ = file.Close()
174 - return nil, err
175 - }
176 -
177 - return file, nil
178 -}
179 -
180 -func isSocketSpaceError(err error) bool {
181 - // checks whether the error is signaling an "overlarge message" condition
182 - var opErr *net.OpError
183 - var sysErr *os.SyscallError
184 -
185 - if !errors.As(err, &opErr) || !errors.As(opErr.Err, &sysErr) {
186 - return false
187 - }
188 -
189 - return errors.Is(sysErr.Err, syscall.EMSGSIZE) || errors.Is(sysErr.Err, syscall.ENOBUFS)
190 -}
src/go/otel-collector/exporter/journaldexporter/metadata.yaml deleted
-7
@@ -1,7 +0,0 @@
1 -type: journaldexporter
2 -github_project: github.com/netdata/netdata/otel-collector/exporter/journaldexporter
3 -
4 -status:
5 - class: exporter
6 - stability:
7 - development: [logs]
src/go/otel-collector/exporter/journaldexporter/sys.go deleted
-73
@@ -1,73 +0,0 @@
1 -package journaldexporter
2 -
3 -import (
4 - "os"
5 - "os/exec"
6 - "regexp"
7 - "runtime"
8 - "strings"
9 -
10 - "github.com/google/uuid"
11 -)
12 -
13 -func getBootID() string {
14 - switch runtime.GOOS {
15 - case "linux":
16 - if bs, err := os.ReadFile("/proc/sys/kernel/random/boot_id"); err == nil {
17 - return strings.TrimSpace(string(bs))
18 - }
19 - case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd":
20 - cmd := exec.Command("sysctl", "kern.boottime")
21 - if bs, err := cmd.Output(); err == nil && len(bs) > 0 {
22 - return uuid.NewSHA1(uuid.NameSpaceDNS, bs).String()
23 - }
24 - case "windows":
25 - cmd := exec.Command("powershell", "-Command",
26 - "(Get-CimInstance -ClassName win32_operatingsystem).LastBootUpTime.ToString('o')")
27 - if bs, err := cmd.Output(); err == nil && len(bs) > 0 {
28 - return uuid.NewSHA1(uuid.NameSpaceDNS, bs).String()
29 - }
30 -
31 - cmd = exec.Command("wmic", "os", "get", "LastBootUpTime")
32 - if bs, err := cmd.Output(); err == nil && len(bs) > 0 {
33 - return uuid.NewSHA1(uuid.NameSpaceDNS, bs).String()
34 - }
35 - }
36 -
37 - return uuid.NewString()
38 -}
39 -
40 -func getMachineID() string {
41 - switch runtime.GOOS {
42 - case "linux":
43 - if bs, err := os.ReadFile("/etc/machine-id"); err == nil {
44 - return strings.TrimSpace(string(bs))
45 - }
46 - case "dragonfly", "freebsd", "netbsd", "openbsd":
47 - if bs, err := os.ReadFile("/etc/hostid"); err == nil {
48 - return strings.TrimSpace(string(bs))
49 - }
50 - case "windows":
51 - cmd := exec.Command("powershell", "-Command",
52 - "Get-ItemProperty -Path 'HKLM:\\SOFTWARE\\Microsoft\\Cryptography' -Name 'MachineGuid'")
53 - if bs, err := cmd.Output(); err == nil && len(bs) > 0 {
54 - re := regexp.MustCompile(`MachineGuid\s+:\s+([0-9a-fA-F-]+)`)
55 - matches := re.FindSubmatch(bs)
56 - if len(matches) >= 2 {
57 - return string(matches[1])
58 - }
59 - }
60 -
61 - cmd = exec.Command("wmic", "csproduct", "get", "UUID")
62 - if bs, err := cmd.Output(); err == nil && len(bs) > 0 {
63 - lines := strings.Split(string(bs), "\n")
64 - if len(lines) > 1 {
65 - return strings.TrimSpace(lines[1])
66 - }
67 - }
68 - }
69 -
70 - hostname, _ := os.Hostname()
71 -
72 - return uuid.NewSHA1(uuid.NameSpaceDNS, []byte(hostname)).String()
73 -}
src/go/otel-collector/exporter/netdataexporter/config.go deleted
-4
@@ -1,4 +0,0 @@
1 -package netdataexporter
2 -
3 -type Config struct {
4 -}
src/go/otel-collector/exporter/netdataexporter/convert.go deleted
-821
@@ -1,821 +0,0 @@
1 -package netdataexporter
2 -
3 -import (
4 - "fmt"
5 - "hash/fnv"
6 - "sort"
7 - "strconv"
8 - "strings"
9 - "unicode"
10 -
11 - "go.opentelemetry.io/collector/pdata/pcommon"
12 - "go.opentelemetry.io/collector/pdata/pmetric"
13 -)
14 -
15 -type ChartDefinition struct {
16 - ID string // must be globally unique
17 - Title string
18 - Units string
19 - Family string
20 - Context string // metric name
21 - Type string // line, area, stacked
22 - Options string // set to "obsolete" to delete the chart, otherwise empty string
23 - Labels []LabelDefinition
24 - Dimensions []DimensionDefinition
25 - IsNew bool // Indicates if this chart is new and needs to be sent to Netdata
26 -}
27 -
28 -// LabelDefinition represents a Netdata chart label
29 -type LabelDefinition struct {
30 - Name string
31 - Value string
32 -}
33 -
34 -// DimensionDefinition represents a Netdata chart dimension
35 -type DimensionDefinition struct {
36 - ID string // must be unique within the chart
37 - Name string // replaces ID in UI
38 - Algo string // absolute (Gauge), incremental (Counter)
39 - Value float64
40 -}
41 -
42 -// Maximum length for chart IDs to prevent excessively long IDs
43 -const maxChartIDLength = 1000
44 -
45 -// Convert transforms OTLP metrics into Netdata charts
46 -func (e *netdataExporter) convert(pms pmetric.Metrics) map[string]*ChartDefinition {
47 - // Track new and updated charts in this batch
48 - currentCharts := make(map[string]bool, len(e.charts))
49 -
50 - for _, rm := range pms.ResourceMetrics().All() {
51 - resAttrs := rm.Resource().Attributes()
52 -
53 - for _, sm := range rm.ScopeMetrics().All() {
54 - for _, metric := range sm.Metrics().All() {
55 - switch metric.Type() {
56 - case pmetric.MetricTypeGauge:
57 - e.processGauge(metric, resAttrs, currentCharts)
58 - case pmetric.MetricTypeSum:
59 - e.processSum(metric, resAttrs, currentCharts)
60 - case pmetric.MetricTypeHistogram:
61 - e.processHistogram(metric, resAttrs, currentCharts)
62 - case pmetric.MetricTypeExponentialHistogram:
63 - e.processExponentialHistogram(metric, resAttrs, currentCharts)
64 - case pmetric.MetricTypeSummary:
65 - e.processSummary(metric, resAttrs, currentCharts)
66 - default:
67 - }
68 - }
69 - }
70 - }
71 -
72 - for id, chart := range e.charts {
73 - if !currentCharts[id] {
74 - chart.IsNew = false
75 - }
76 - }
77 -
78 - return e.charts
79 -}
80 -
81 -// processGauge handles gauge metric types
82 -func (e *netdataExporter) processGauge(metric pmetric.Metric, resourceAttrs pcommon.Map, currentCharts map[string]bool) {
83 - gauge := metric.Gauge()
84 - metricName := metric.Name()
85 -
86 - // Group data points by their attributes to create separate charts
87 - attributeGroups := groupDataPointsByAttributes(gauge.DataPoints())
88 -
89 - for attrHash, points := range attributeGroups {
90 - // Generate a unique chart ID
91 - chartID := generateChartID(metricName, attrHash)
92 - currentCharts[chartID] = true
93 -
94 - // Get or create chart
95 - chart, exists := e.charts[chartID]
96 - if !exists {
97 - chart = &ChartDefinition{
98 - ID: chartID,
99 - Title: getTitle(metric),
100 - Units: getUnits(metric),
101 - Family: getFamily(metricName, resourceAttrs),
102 - Context: metricName,
103 - Type: "line", // Default to line chart
104 - Labels: make([]LabelDefinition, 0, resourceAttrs.Len()),
105 - IsNew: true,
106 - }
107 - e.charts[chartID] = chart
108 - }
109 -
110 - // Update chart with resource attributes as labels
111 - updateChartLabels(chart, resourceAttrs)
112 -
113 - // Process data points
114 - dimensions := make([]DimensionDefinition, 0, len(points))
115 -
116 - for _, dp := range points {
117 - if dp.Flags().NoRecordedValue() {
118 - continue
119 - }
120 -
121 - dimID := generateDimensionID(dp.Attributes())
122 - dimName := getDimensionName(dp.Attributes())
123 -
124 - value := 0.0
125 - if dp.ValueType() == pmetric.NumberDataPointValueTypeDouble {
126 - value = dp.DoubleValue()
127 - } else {
128 - value = float64(dp.IntValue())
129 - }
130 -
131 - dimensions = append(dimensions, DimensionDefinition{
132 - ID: dimID,
133 - Name: dimName,
134 - Algo: "absolute", // Gauge uses absolute algorithm
135 - Value: value,
136 - })
137 -
138 - // Add data point attributes as labels
139 - addDataPointAttributesAsLabels(chart, dp.Attributes())
140 - }
141 -
142 - chart.Dimensions = append(chart.Dimensions[:0], dimensions...)
143 - }
144 -}
145 -
146 -// processSum handles sum metric types
147 -func (e *netdataExporter) processSum(metric pmetric.Metric, resourceAttrs pcommon.Map, currentCharts map[string]bool) {
148 - sum := metric.Sum()
149 - metricName := metric.Name()
150 -
151 - // Determine algorithm based on aggregation temporality
152 - algo := "absolute" // Default for CUMULATIVE and UNSPECIFIED
153 - if sum.AggregationTemporality() == pmetric.AggregationTemporalityDelta {
154 - algo = "incremental"
155 - }
156 -
157 - // Group data points by their attributes to create separate charts
158 - attributeGroups := groupDataPointsByAttributes(sum.DataPoints())
159 -
160 - for attrHash, points := range attributeGroups {
161 - // Generate a unique chart ID
162 - chartID := generateChartID(metricName, attrHash)
163 - currentCharts[chartID] = true
164 -
165 - // Get or create chart
166 - chart, exists := e.charts[chartID]
167 - if !exists {
168 - chart = &ChartDefinition{
169 - ID: chartID,
170 - Title: getTitle(metric),
171 - Units: getUnits(metric),
172 - Family: getFamily(metricName, resourceAttrs),
173 - Context: metricName,
174 - Type: "line", // Default to line chart
175 - Labels: make([]LabelDefinition, 0, resourceAttrs.Len()),
176 - IsNew: true,
177 - }
178 - e.charts[chartID] = chart
179 - }
180 -
181 - // Update chart with resource attributes as labels
182 - updateChartLabels(chart, resourceAttrs)
183 -
184 - // Process data points
185 - dimensions := make([]DimensionDefinition, 0, len(points))
186 -
187 - for _, dp := range points {
188 - if dp.Flags().NoRecordedValue() {
189 - continue
190 - }
191 -
192 - dimID := generateDimensionID(dp.Attributes())
193 - dimName := getDimensionName(dp.Attributes())
194 -
195 - value := 0.0
196 - if dp.ValueType() == pmetric.NumberDataPointValueTypeDouble {
197 - value = dp.DoubleValue()
198 - } else {
199 - value = float64(dp.IntValue())
200 - }
201 -
202 - dimensions = append(dimensions, DimensionDefinition{
203 - ID: dimID,
204 - Name: dimName,
205 - Algo: algo,
206 - Value: value,
207 - })
208 -
209 - // Add data point attributes as labels
210 - addDataPointAttributesAsLabels(chart, dp.Attributes())
211 - }
212 -
213 - chart.Dimensions = dimensions
214 - }
215 -}
216 -
217 -// processHistogram handles histogram metric types
218 -func (e *netdataExporter) processHistogram(metric pmetric.Metric, resourceAttrs pcommon.Map, currentCharts map[string]bool) {
219 - histogram := metric.Histogram()
220 - metricName := metric.Name()
221 -
222 - // Determine algorithm based on aggregation temporality
223 - algo := "absolute" // Default for CUMULATIVE and UNSPECIFIED
224 - if histogram.AggregationTemporality() == pmetric.AggregationTemporalityDelta {
225 - algo = "incremental"
226 - }
227 -
228 - for _, dp := range histogram.DataPoints().All() {
229 - if dp.Flags().NoRecordedValue() {
230 - continue
231 - }
232 -
233 - attrHash := attributesHash(dp.Attributes())
234 - dimID := generateDimensionID(dp.Attributes())
235 - dimName := getDimensionName(dp.Attributes())
236 -
237 - // 1. Count chart
238 - countChartID := generateChartID(metricName+".count", attrHash)
239 - currentCharts[countChartID] = true
240 -
241 - countChart, exists := e.charts[countChartID]
242 - if !exists {
243 - countChart = &ChartDefinition{
244 - ID: countChartID,
245 - Title: getTitle(metric) + " (Count)",
246 - Units: "count",
247 - Family: getFamily(metricName, resourceAttrs),
248 - Context: metricName + ".count",
249 - Type: "line",
250 - Labels: make([]LabelDefinition, 0, resourceAttrs.Len()),
251 - IsNew: true,
252 - }
253 - e.charts[countChartID] = countChart
254 - }
255 -
256 - updateChartLabels(countChart, resourceAttrs)
257 - addDataPointAttributesAsLabels(countChart, dp.Attributes())
258 -
259 - countChart.Dimensions = []DimensionDefinition{
260 - {
261 - ID: dimID,
262 - Name: dimName,
263 - Algo: algo,
264 - Value: float64(dp.Count()),
265 - },
266 - }
267 -
268 - // 2. Sum chart (if sum exists)
269 - if dp.HasSum() {
270 - sumChartID := generateChartID(metricName+".sum", attrHash)
271 - currentCharts[sumChartID] = true
272 -
273 - sumChart, exists := e.charts[sumChartID]
274 - if !exists {
275 - sumChart = &ChartDefinition{
276 - ID: sumChartID,
277 - Title: getTitle(metric) + " (Sum)",
278 - Units: getUnits(metric),
279 - Family: getFamily(metricName, resourceAttrs),
280 - Context: metricName + ".sum",
281 - Type: "line",
282 - Labels: make([]LabelDefinition, 0, resourceAttrs.Len()),
283 - IsNew: true,
284 - }
285 - e.charts[sumChartID] = sumChart
286 - }
287 -
288 - updateChartLabels(sumChart, resourceAttrs)
289 - addDataPointAttributesAsLabels(sumChart, dp.Attributes())
290 -
291 - sumChart.Dimensions = []DimensionDefinition{
292 - {
293 - ID: dimID,
294 - Name: dimName,
295 - Algo: algo,
296 - Value: dp.Sum(),
297 - },
298 - }
299 - }
300 -
301 - // 3. Buckets chart (if buckets exist)
302 - bucketCounts := dp.BucketCounts()
303 - explicitBounds := dp.ExplicitBounds()
304 -
305 - if bucketCounts.Len() > 0 && explicitBounds.Len() > 0 {
306 - bucketsChartID := generateChartID(metricName+".buckets", attrHash)
307 - currentCharts[bucketsChartID] = true
308 -
309 - bucketsChart, exists := e.charts[bucketsChartID]
310 - if !exists {
311 - bucketsChart = &ChartDefinition{
312 - ID: bucketsChartID,
313 - Title: getTitle(metric) + " (Buckets)",
314 - Units: "count",
315 - Family: getFamily(metricName, resourceAttrs),
316 - Context: metricName + ".buckets",
317 - Type: "stacked", // Histogram buckets should be stacked
318 - Labels: make([]LabelDefinition, 0, resourceAttrs.Len()),
319 - IsNew: true,
320 - }
321 - e.charts[bucketsChartID] = bucketsChart
322 - }
323 -
324 - updateChartLabels(bucketsChart, resourceAttrs)
325 - addDataPointAttributesAsLabels(bucketsChart, dp.Attributes())
326 -
327 - dimensions := make([]DimensionDefinition, 0, bucketCounts.Len())
328 -
329 - // Add dimensions for each bucket
330 - for j := 0; j < bucketCounts.Len(); j++ {
331 - var upperBound string
332 - if j < explicitBounds.Len() {
333 - upperBound = fmt.Sprintf("%.2f", explicitBounds.At(j))
334 - } else {
335 - upperBound = "inf"
336 - }
337 -
338 - bucketDimID := dimID + "_bucket_" + strconv.Itoa(j)
339 - bucketDimName := "≤ " + upperBound
340 -
341 - dimensions = append(dimensions, DimensionDefinition{
342 - ID: bucketDimID,
343 - Name: bucketDimName,
344 - Algo: algo,
345 - Value: float64(bucketCounts.At(j)),
346 - })
347 - }
348 -
349 - bucketsChart.Dimensions = dimensions
350 - }
351 - }
352 -}
353 -
354 -// processExponentialHistogram handles exponential histogram metric types
355 -func (e *netdataExporter) processExponentialHistogram(metric pmetric.Metric, resourceAttrs pcommon.Map, currentCharts map[string]bool) {
356 - expHistogram := metric.ExponentialHistogram()
357 - metricName := metric.Name()
358 -
359 - // Determine algorithm based on aggregation temporality
360 - algo := "absolute" // Default for CUMULATIVE and UNSPECIFIED
361 - if expHistogram.AggregationTemporality() == pmetric.AggregationTemporalityDelta {
362 - algo = "incremental"
363 - }
364 -
365 - for _, dp := range expHistogram.DataPoints().All() {
366 - if dp.Flags().NoRecordedValue() {
367 - continue
368 - }
369 -
370 - attrHash := attributesHash(dp.Attributes())
371 - dimID := generateDimensionID(dp.Attributes())
372 - dimName := getDimensionName(dp.Attributes())
373 -
374 - // 1. Count chart
375 - countChartID := generateChartID(metricName+".count", attrHash)
376 - currentCharts[countChartID] = true
377 -
378 - countChart, exists := e.charts[countChartID]
379 - if !exists {
380 - countChart = &ChartDefinition{
381 - ID: countChartID,
382 - Title: getTitle(metric) + " (Count)",
383 - Units: "count",
384 - Family: getFamily(metricName, resourceAttrs),
385 - Context: metricName + ".count",
386 - Type: "line",
387 - Labels: make([]LabelDefinition, 0, resourceAttrs.Len()),
388 - IsNew: true,
389 - }
390 - e.charts[countChartID] = countChart
391 - }
392 -
393 - updateChartLabels(countChart, resourceAttrs)
394 - addDataPointAttributesAsLabels(countChart, dp.Attributes())
395 -
396 - countChart.Dimensions = []DimensionDefinition{
397 - {
398 - ID: dimID,
399 - Name: dimName,
400 - Algo: algo,
401 - Value: float64(dp.Count()),
402 - },
403 - }
404 -
405 - // 2. Sum chart (if sum exists)
406 - if dp.HasSum() {
407 - sumChartID := generateChartID(metricName+".sum", attrHash)
408 - currentCharts[sumChartID] = true
409 -
410 - sumChart, exists := e.charts[sumChartID]
411 - if !exists {
412 - sumChart = &ChartDefinition{
413 - ID: sumChartID,
414 - Title: getTitle(metric) + " (Sum)",
415 - Units: getUnits(metric),
416 - Family: getFamily(metricName, resourceAttrs),
417 - Context: metricName + ".sum",
418 - Type: "line",
419 - Labels: make([]LabelDefinition, 0, resourceAttrs.Len()),
420 - IsNew: true,
421 - }
422 - e.charts[sumChartID] = sumChart
423 - }
424 -
425 - updateChartLabels(sumChart, resourceAttrs)
426 - addDataPointAttributesAsLabels(sumChart, dp.Attributes())
427 -
428 - sumChart.Dimensions = []DimensionDefinition{
429 - {
430 - ID: dimID,
431 - Name: dimName,
432 - Algo: algo,
433 - Value: dp.Sum(),
434 - },
435 - }
436 - }
437 -
438 - // 3. Simplified histogram buckets chart
439 - // For exponential histograms, we'll create a simplified view with positive, zero, and negative counts
440 - bucketsChartID := generateChartID(metricName+".exp_buckets", attrHash)
441 - currentCharts[bucketsChartID] = true
442 -
443 - bucketsChart, exists := e.charts[bucketsChartID]
444 - if !exists {
445 - bucketsChart = &ChartDefinition{
446 - ID: bucketsChartID,
447 - Title: getTitle(metric) + " (Distribution)",
448 - Units: "count",
449 - Family: getFamily(metricName, resourceAttrs),
450 - Context: metricName + ".distribution",
451 - Type: "stacked",
452 - Labels: make([]LabelDefinition, 0, resourceAttrs.Len()),
453 - IsNew: true,
454 - }
455 - e.charts[bucketsChartID] = bucketsChart
456 - }
457 -
458 - updateChartLabels(bucketsChart, resourceAttrs)
459 - addDataPointAttributesAsLabels(bucketsChart, dp.Attributes())
460 -
461 - // Add dimensions for positive, negative, and zero buckets
462 - bucketsChart.Dimensions = []DimensionDefinition{
463 - {
464 - ID: dimID + "_positive",
465 - Name: "Positive Values",
466 - Algo: algo,
467 - Value: getTotalCountFromBuckets(dp.Positive()),
468 - },
469 - {
470 - ID: dimID + "_zero",
471 - Name: "Zero Values",
472 - Algo: algo,
473 - Value: float64(dp.ZeroCount()),
474 - },
475 - {
476 - ID: dimID + "_negative",
477 - Name: "Negative Values",
478 - Algo: algo,
479 - Value: getTotalCountFromBuckets(dp.Negative()),
480 - },
481 - }
482 - }
483 -}
484 -
485 -// processSummary handles summary metric types
486 -func (e *netdataExporter) processSummary(metric pmetric.Metric, resourceAttrs pcommon.Map, currentCharts map[string]bool) {
487 - summary := metric.Summary()
488 - metricName := metric.Name()
489 -
490 - for _, dp := range summary.DataPoints().All() {
491 - if dp.Flags().NoRecordedValue() {
492 - continue
493 - }
494 -
495 - attrHash := attributesHash(dp.Attributes())
496 - dimID := generateDimensionID(dp.Attributes())
497 - dimName := getDimensionName(dp.Attributes())
498 -
499 - // 1. Count chart
500 - countChartID := generateChartID(metricName+".count", attrHash)
501 - currentCharts[countChartID] = true
502 -
503 - countChart, exists := e.charts[countChartID]
504 - if !exists {
505 - countChart = &ChartDefinition{
506 - ID: countChartID,
507 - Title: getTitle(metric) + " (Count)",
508 - Units: "count",
509 - Family: getFamily(metricName, resourceAttrs),
510 - Context: metricName + ".count",
511 - Type: "line",
512 - Labels: make([]LabelDefinition, 0, resourceAttrs.Len()),
513 - IsNew: true,
514 - }
515 - e.charts[countChartID] = countChart
516 - }
517 -
518 - updateChartLabels(countChart, resourceAttrs)
519 - addDataPointAttributesAsLabels(countChart, dp.Attributes())
520 -
521 - countChart.Dimensions = []DimensionDefinition{
522 - {
523 - ID: dimID,
524 - Name: dimName,
525 - Algo: "absolute", // Summary count should be absolute
526 - Value: float64(dp.Count()),
527 - },
528 - }
529 -
530 - // 2. Sum chart
531 - sumChartID := generateChartID(metricName+".sum", attrHash)
532 - currentCharts[sumChartID] = true
533 -
534 - sumChart, exists := e.charts[sumChartID]
535 - if !exists {
536 - sumChart = &ChartDefinition{
537 - ID: sumChartID,
538 - Title: getTitle(metric) + " (Sum)",
539 - Units: getUnits(metric),
540 - Family: getFamily(metricName, resourceAttrs),
541 - Context: metricName + ".sum",
542 - Type: "line",
543 - Labels: make([]LabelDefinition, 0, resourceAttrs.Len()),
544 - IsNew: true,
545 - }
546 - e.charts[sumChartID] = sumChart
547 - }
548 -
549 - updateChartLabels(sumChart, resourceAttrs)
550 - addDataPointAttributesAsLabels(sumChart, dp.Attributes())
551 -
552 - sumChart.Dimensions = []DimensionDefinition{
553 - {
554 - ID: dimID,
555 - Name: dimName,
556 - Algo: "absolute", // Summary sum should be absolute
557 - Value: dp.Sum(),
558 - },
559 - }
560 -
561 - // 3. Quantiles chart
562 - qvs := dp.QuantileValues()
563 - if qvs.Len() > 0 {
564 - quantilesChartID := generateChartID(metricName+".quantiles", attrHash)
565 - currentCharts[quantilesChartID] = true
566 -
567 - quantilesChart, exists := e.charts[quantilesChartID]
568 - if !exists {
569 - quantilesChart = &ChartDefinition{
570 - ID: quantilesChartID,
571 - Title: getTitle(metric) + " (Quantiles)",
572 - Units: getUnits(metric),
573 - Family: getFamily(metricName, resourceAttrs),
574 - Context: metricName + ".quantiles",
575 - Type: "line",
576 - Labels: make([]LabelDefinition, 0, resourceAttrs.Len()),
577 - IsNew: true,
578 - }
579 - e.charts[quantilesChartID] = quantilesChart
580 - }
581 -
582 - updateChartLabels(quantilesChart, resourceAttrs)
583 - addDataPointAttributesAsLabels(quantilesChart, dp.Attributes())
584 -
585 - dimensions := make([]DimensionDefinition, 0, qvs.Len())
586 -
587 - // Add dimensions for each quantile
588 - for _, qv := range qvs.All() {
589 - quantileStr := fmt.Sprintf("%.2f", qv.Quantile())
590 -
591 - // Special names for min/max
592 - var quantileName string
593 - if qv.Quantile() == 0 {
594 - quantileName = "min"
595 - } else if qv.Quantile() == 1 {
596 - quantileName = "max"
597 - } else {
598 - quantileName = "p" + strings.ReplaceAll(quantileStr, "0.", "")
599 - }
600 -
601 - dimensions = append(dimensions, DimensionDefinition{
602 - ID: dimID + "_q" + strings.ReplaceAll(quantileStr, ".", "_"),
603 - Name: quantileName,
604 - Algo: "absolute", // Quantiles are absolute values
605 - Value: qv.Value(),
606 - })
607 - }
608 -
609 - quantilesChart.Dimensions = dimensions
610 - }
611 - }
612 -}
613 -
614 -// groupDataPointsByAttributes groups data points by attributes to create separate charts
615 -func groupDataPointsByAttributes(dataPoints pmetric.NumberDataPointSlice) map[string][]pmetric.NumberDataPoint {
616 - groups := make(map[string][]pmetric.NumberDataPoint)
617 -
618 - for _, dp := range dataPoints.All() {
619 - hash := attributesHash(dp.Attributes())
620 - groups[hash] = append(groups[hash], dp)
621 - }
622 -
623 - return groups
624 -}
625 -
626 -func generateChartID(metricName, attrHash string) string {
627 - // Sanitize and limit the length of the metric name to prevent overly long IDs
628 - sanitizedName := sanitizeID(metricName)
629 - if len(sanitizedName) > maxChartIDLength-1-len(attrHash) {
630 - sanitizedName = sanitizedName[:maxChartIDLength-1-len(attrHash)]
631 - }
632 - return sanitizedName + "_" + attrHash
633 -}
634 -
635 -func generateDimensionID(attrs pcommon.Map) string {
636 - if attrs.Len() == 0 {
637 - return "value"
638 - }
639 -
640 - return "value_" + attributesHash(attrs)
641 -}
642 -
643 -func getDimensionName(attrs pcommon.Map) string {
644 - if attrs.Len() == 0 {
645 - return "value"
646 - }
647 -
648 - // Try to find a good name from the attributes
649 - nameAttrs := []string{"name", "id", "key"}
650 - for _, nameAttr := range nameAttrs {
651 - if val, ok := attrs.Get(nameAttr); ok {
652 - return val.AsString()
653 - }
654 - }
655 -
656 - return "value"
657 -}
658 -
659 -func getTitle(metric pmetric.Metric) string {
660 - if metric.Description() != "" {
661 - return metric.Description()
662 - }
663 - return metric.Name()
664 -}
665 -
666 -func getUnits(metric pmetric.Metric) string {
667 - if metric.Unit() != "" {
668 - return metric.Unit()
669 - }
670 - return "count" // Default unit
671 -}
672 -
673 -func getFamily(metricName string, resourceAttrs pcommon.Map) string {
674 - var sb strings.Builder
675 -
676 - if val, ok := resourceAttrs.Get("service.name"); ok {
677 - sb.WriteString(sanitizeID(val.AsString()))
678 - } else if val, ok := resourceAttrs.Get("service.namespace"); ok {
679 - sb.WriteString(sanitizeID(val.AsString()))
680 - }
681 -
682 - // Split the metric name
683 - parts := strings.Split(metricName, ".")
684 - prefix := metricName
685 - if len(parts) > 1 {
686 - prefix = parts[0]
687 - }
688 -
689 - if sb.Len() > 0 {
690 - sb.WriteString("_")
691 - }
692 - sb.WriteString(sanitizeID(prefix))
693 -
694 - return sb.String()
695 -}
696 -
697 -func updateChartLabels(chart *ChartDefinition, resourceAttrs pcommon.Map) {
698 - if len(chart.Labels) == resourceAttrs.Len() {
699 - same := true
700 - resourceAttrs.Range(func(key string, value pcommon.Value) bool {
701 - found := false
702 - for _, label := range chart.Labels {
703 - if label.Name == key && label.Value == value.AsString() {
704 - found = true
705 - break
706 - }
707 - }
708 - if !found {
709 - same = false
710 - return false
711 - }
712 - return true
713 - })
714 - if same {
715 - return
716 - }
717 - }
718 -
719 - chart.Labels = make([]LabelDefinition, 0, resourceAttrs.Len())
720 -
721 - resourceAttrs.Range(func(key string, value pcommon.Value) bool {
722 - chart.Labels = append(chart.Labels, LabelDefinition{
723 - Name: key,
724 - Value: value.AsString(),
725 - })
726 - return true
727 - })
728 -
729 - sort.Slice(chart.Labels, func(i, j int) bool {
730 - return chart.Labels[i].Name < chart.Labels[j].Name
731 - })
732 -}
733 -
734 -func addDataPointAttributesAsLabels(chart *ChartDefinition, attrs pcommon.Map) {
735 - // Use a map to track existing labels by name for O(1) lookup
736 - existingLabels := make(map[string]bool, len(chart.Labels))
737 - for _, label := range chart.Labels {
738 - existingLabels[label.Name] = true
739 - }
740 -
741 - var newLabels []LabelDefinition
742 - attrs.Range(func(key string, value pcommon.Value) bool {
743 - if !existingLabels[key] {
744 - newLabels = append(newLabels, LabelDefinition{
745 - Name: key,
746 - Value: value.AsString(),
747 - })
748 - existingLabels[key] = true
749 - }
750 - return true
751 - })
752 -
753 - if len(newLabels) > 0 {
754 - chart.Labels = append(chart.Labels, newLabels...)
755 -
756 - // Sort labels by name for consistent output
757 - sort.Slice(chart.Labels, func(i, j int) bool {
758 - return chart.Labels[i].Name < chart.Labels[j].Name
759 - })
760 - }
761 -}
762 -
763 -func attributesHash(attrs pcommon.Map) string {
764 - if attrs.Len() == 0 {
765 - return "default"
766 - }
767 -
768 - hash := fnv.New64a()
769 -
770 - // Sort keys for consistent hashing
771 - keys := make([]string, 0, attrs.Len())
772 - attrs.Range(func(k string, v pcommon.Value) bool {
773 - keys = append(keys, k)
774 - return true
775 - })
776 - sort.Strings(keys)
777 -
778 - for _, k := range keys {
779 - v, _ := attrs.Get(k)
780 - _, _ = hash.Write([]byte(k))
781 - _, _ = hash.Write([]byte(":"))
782 - _, _ = hash.Write([]byte(v.AsString()))
783 - _, _ = hash.Write([]byte(";"))
784 - }
785 -
786 - return strconv.FormatUint(hash.Sum64(), 16)
787 -}
788 -
789 -func sanitizeID(name string) string {
790 - if name == "" {
791 - return "unknown"
792 - }
793 -
794 - var sb strings.Builder
795 - sb.Grow(len(name))
796 -
797 - // Ensure the ID doesn't start with a number
798 - if unicode.IsDigit(rune(name[0])) {
799 - sb.WriteString("n_")
800 - }
801 -
802 - for _, r := range name {
803 - switch {
804 - case unicode.IsLetter(r), unicode.IsDigit(r), r == '_', r == '.', r == '-':
805 - sb.WriteRune(r)
806 - default:
807 - sb.WriteRune('_')
808 - }
809 - }
810 -
811 - return sb.String()
812 -}
813 -
814 -func getTotalCountFromBuckets(buckets pmetric.ExponentialHistogramDataPointBuckets) float64 {
815 - counts := buckets.BucketCounts()
816 - var sum uint64
817 - for i := 0; i < counts.Len(); i++ {
818 - sum += counts.At(i)
819 - }
820 - return float64(sum)
821 -}
src/go/otel-collector/exporter/netdataexporter/convert_test.go deleted
-657
@@ -1,657 +0,0 @@
1 -package netdataexporter
2 -
3 -import (
4 - "strings"
5 - "testing"
6 -
7 - "github.com/stretchr/testify/assert"
8 - "github.com/stretchr/testify/require"
9 - "go.opentelemetry.io/collector/pdata/pcommon"
10 - "go.opentelemetry.io/collector/pdata/pmetric"
11 -)
12 -
13 -func TestNetdataExporter_Convert(t *testing.T) {
14 - tests := map[string]struct {
15 - inputMetrics func() pmetric.Metrics
16 - expectedChartCount int
17 - expectedCharts map[string]ChartDefinition
18 - }{
19 - "gauge_metric": {
20 - inputMetrics: func() pmetric.Metrics {
21 - metrics := pmetric.NewMetrics()
22 - rm := metrics.ResourceMetrics().AppendEmpty()
23 -
24 - // Add resource attributes
25 - rm.Resource().Attributes().PutStr("service.name", "test-service")
26 -
27 - sm := rm.ScopeMetrics().AppendEmpty()
28 - metric := sm.Metrics().AppendEmpty()
29 - metric.SetName("test.gauge")
30 - metric.SetDescription("Test Gauge")
31 - metric.SetUnit("bytes")
32 -
33 - gauge := metric.SetEmptyGauge()
34 - dp := gauge.DataPoints().AppendEmpty()
35 - dp.SetDoubleValue(42.0)
36 - dp.Attributes().PutStr("host", "test-host")
37 -
38 - return metrics
39 - },
40 - expectedChartCount: 1,
41 - expectedCharts: map[string]ChartDefinition{},
42 - },
43 - "sum_metric_delta": {
44 - inputMetrics: func() pmetric.Metrics {
45 - metrics := pmetric.NewMetrics()
46 - rm := metrics.ResourceMetrics().AppendEmpty()
47 -
48 - sm := rm.ScopeMetrics().AppendEmpty()
49 - metric := sm.Metrics().AppendEmpty()
50 - metric.SetName("test.sum")
51 - metric.SetDescription("Test Sum")
52 - metric.SetUnit("count")
53 -
54 - sum := metric.SetEmptySum()
55 - sum.SetAggregationTemporality(pmetric.AggregationTemporalityDelta)
56 - sum.SetIsMonotonic(true)
57 -
58 - dp := sum.DataPoints().AppendEmpty()
59 - dp.SetIntValue(100)
60 -
61 - return metrics
62 - },
63 - expectedChartCount: 1,
64 - expectedCharts: map[string]ChartDefinition{},
65 - },
66 - "sum_metric_cumulative": {
67 - inputMetrics: func() pmetric.Metrics {
68 - metrics := pmetric.NewMetrics()
69 - rm := metrics.ResourceMetrics().AppendEmpty()
70 -
71 - sm := rm.ScopeMetrics().AppendEmpty()
72 - metric := sm.Metrics().AppendEmpty()
73 - metric.SetName("test.sum")
74 - metric.SetDescription("Test Sum")
75 - metric.SetUnit("count")
76 -
77 - sum := metric.SetEmptySum()
78 - sum.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
79 - sum.SetIsMonotonic(true)
80 -
81 - dp := sum.DataPoints().AppendEmpty()
82 - dp.SetIntValue(100)
83 -
84 - return metrics
85 - },
86 - expectedChartCount: 1,
87 - expectedCharts: map[string]ChartDefinition{},
88 - },
89 - "histogram_metric": {
90 - inputMetrics: func() pmetric.Metrics {
91 - metrics := pmetric.NewMetrics()
92 - rm := metrics.ResourceMetrics().AppendEmpty()
93 -
94 - sm := rm.ScopeMetrics().AppendEmpty()
95 - metric := sm.Metrics().AppendEmpty()
96 - metric.SetName("test.histogram")
97 - metric.SetDescription("Test Histogram")
98 - metric.SetUnit("ms")
99 -
100 - histogram := metric.SetEmptyHistogram()
101 - histogram.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
102 -
103 - dp := histogram.DataPoints().AppendEmpty()
104 - dp.SetCount(30)
105 - dp.SetSum(200.0)
106 - dp.BucketCounts().FromRaw([]uint64{10, 15, 5})
107 - dp.ExplicitBounds().FromRaw([]float64{10.0, 20.0})
108 -
109 - return metrics
110 - },
111 - expectedChartCount: 3, // Count, Sum, and Buckets charts
112 - expectedCharts: map[string]ChartDefinition{},
113 - },
114 - "exponential_histogram_metric": {
115 - inputMetrics: func() pmetric.Metrics {
116 - metrics := pmetric.NewMetrics()
117 - rm := metrics.ResourceMetrics().AppendEmpty()
118 -
119 - sm := rm.ScopeMetrics().AppendEmpty()
120 - metric := sm.Metrics().AppendEmpty()
121 - metric.SetName("test.exponential_histogram")
122 - metric.SetDescription("Test Exponential Histogram")
123 - metric.SetUnit("ms")
124 -
125 - expHistogram := metric.SetEmptyExponentialHistogram()
126 - expHistogram.SetAggregationTemporality(pmetric.AggregationTemporalityDelta)
127 -
128 - dp := expHistogram.DataPoints().AppendEmpty()
129 - dp.SetCount(30)
130 - dp.SetSum(200.0)
131 - dp.SetZeroCount(5)
132 -
133 - // Set up positive buckets
134 - dp.Positive().SetOffset(0)
135 - dp.Positive().BucketCounts().FromRaw([]uint64{10, 5})
136 -
137 - // Set up negative buckets
138 - dp.Negative().SetOffset(0)
139 - dp.Negative().BucketCounts().FromRaw([]uint64{7, 3})
140 -
141 - return metrics
142 - },
143 - expectedChartCount: 3, // Count, Sum, and Distribution charts
144 - expectedCharts: map[string]ChartDefinition{},
145 - },
146 - "summary_metric": {
147 - inputMetrics: func() pmetric.Metrics {
148 - metrics := pmetric.NewMetrics()
149 - rm := metrics.ResourceMetrics().AppendEmpty()
150 -
151 - sm := rm.ScopeMetrics().AppendEmpty()
152 - metric := sm.Metrics().AppendEmpty()
153 - metric.SetName("test.summary")
154 - metric.SetDescription("Test Summary")
155 - metric.SetUnit("ms")
156 -
157 - summary := metric.SetEmptySummary()
158 -
159 - dp := summary.DataPoints().AppendEmpty()
160 - dp.SetCount(100)
161 - dp.SetSum(5000.0)
162 -
163 - // Add quantiles (0%, 50%, 95%, 99%, 100%)
164 - qv := dp.QuantileValues().AppendEmpty()
165 - qv.SetQuantile(0.0)
166 - qv.SetValue(1.0)
167 -
168 - qv = dp.QuantileValues().AppendEmpty()
169 - qv.SetQuantile(0.5)
170 - qv.SetValue(5.0)
171 -
172 - qv = dp.QuantileValues().AppendEmpty()
173 - qv.SetQuantile(0.95)
174 - qv.SetValue(9.5)
175 -
176 - qv = dp.QuantileValues().AppendEmpty()
177 - qv.SetQuantile(0.99)
178 - qv.SetValue(10.0)
179 -
180 - qv = dp.QuantileValues().AppendEmpty()
181 - qv.SetQuantile(1.0)
182 - qv.SetValue(100.0)
183 -
184 - return metrics
185 - },
186 - expectedChartCount: 3, // Count, Sum, and Quantiles charts
187 - expectedCharts: map[string]ChartDefinition{},
188 - },
189 - "multiple_data_points_by_attribute": {
190 - inputMetrics: func() pmetric.Metrics {
191 - metrics := pmetric.NewMetrics()
192 - rm := metrics.ResourceMetrics().AppendEmpty()
193 -
194 - sm := rm.ScopeMetrics().AppendEmpty()
195 - metric := sm.Metrics().AppendEmpty()
196 - metric.SetName("test.gauge.multi")
197 - metric.SetDescription("Test Gauge with Multiple Points")
198 - metric.SetUnit("bytes")
199 -
200 - gauge := metric.SetEmptyGauge()
201 -
202 - // First data point with host=server1
203 - dp1 := gauge.DataPoints().AppendEmpty()
204 - dp1.SetDoubleValue(100.0)
205 - dp1.Attributes().PutStr("host", "server1")
206 -
207 - // Second data point with host=server2
208 - dp2 := gauge.DataPoints().AppendEmpty()
209 - dp2.SetDoubleValue(200.0)
210 - dp2.Attributes().PutStr("host", "server2")
211 -
212 - return metrics
213 - },
214 - expectedChartCount: 2, // One chart per unique attribute set
215 - expectedCharts: map[string]ChartDefinition{},
216 - },
217 - "staleness_marker": {
218 - inputMetrics: func() pmetric.Metrics {
219 - metrics := pmetric.NewMetrics()
220 - rm := metrics.ResourceMetrics().AppendEmpty()
221 -
222 - sm := rm.ScopeMetrics().AppendEmpty()
223 - metric := sm.Metrics().AppendEmpty()
224 - metric.SetName("test.gauge.stale")
225 - metric.SetDescription("Test Gauge with Staleness Marker")
226 -
227 - gauge := metric.SetEmptyGauge()
228 -
229 - // Normal data point
230 - dp1 := gauge.DataPoints().AppendEmpty()
231 - dp1.SetDoubleValue(100.0)
232 -
233 - // Stale data point (with staleness flag set)
234 - dp2 := gauge.DataPoints().AppendEmpty()
235 - dp2.SetDoubleValue(0.0)
236 - dp2.SetFlags(1) // Set staleness marker flag
237 -
238 - return metrics
239 - },
240 - expectedChartCount: 1,
241 - expectedCharts: map[string]ChartDefinition{},
242 - },
243 - "resource_and_datapoint_attributes_as_labels": {
244 - inputMetrics: func() pmetric.Metrics {
245 - metrics := pmetric.NewMetrics()
246 - rm := metrics.ResourceMetrics().AppendEmpty()
247 -
248 - // Add resource attributes
249 - rm.Resource().Attributes().PutStr("service.name", "test-service")
250 - rm.Resource().Attributes().PutStr("deployment.environment", "production")
251 -
252 - sm := rm.ScopeMetrics().AppendEmpty()
253 - metric := sm.Metrics().AppendEmpty()
254 - metric.SetName("test.labels")
255 -
256 - gauge := metric.SetEmptyGauge()
257 - dp := gauge.DataPoints().AppendEmpty()
258 - dp.SetDoubleValue(42.0)
259 -
260 - // Add data point attributes
261 - dp.Attributes().PutStr("host", "host1")
262 - dp.Attributes().PutStr("region", "us-west")
263 -
264 - return metrics
265 - },
266 - expectedChartCount: 1,
267 - expectedCharts: map[string]ChartDefinition{},
268 - },
269 - }
270 -
271 - for name, tt := range tests {
272 - t.Run(name, func(t *testing.T) {
273 - // Create a new exporter for each test to avoid state between tests
274 - exporter := &netdataExporter{
275 - charts: make(map[string]*ChartDefinition),
276 - }
277 -
278 - // Convert the metrics
279 - inputMetrics := tt.inputMetrics()
280 - charts := exporter.Convert(inputMetrics)
281 -
282 - // Verify the chart count
283 - assert.Equal(t, tt.expectedChartCount, len(charts), "Wrong number of charts created")
284 -
285 - switch name {
286 - case "gauge_metric":
287 - // Find the chart for the gauge metric
288 - var gaugeChart *ChartDefinition
289 - for _, chart := range charts {
290 - if chart.Context == "test.gauge" {
291 - gaugeChart = chart
292 - break
293 - }
294 - }
295 - require.NotNil(t, gaugeChart, "Gauge chart should exist")
296 - assert.Equal(t, "Test Gauge", gaugeChart.Title)
297 - assert.Equal(t, "bytes", gaugeChart.Units)
298 - assert.Equal(t, "test-service_test", gaugeChart.Family)
299 - assert.Equal(t, "line", gaugeChart.Type)
300 - assert.Len(t, gaugeChart.Dimensions, 1)
301 - assert.Equal(t, 42.0, gaugeChart.Dimensions[0].Value)
302 - assert.Equal(t, "absolute", gaugeChart.Dimensions[0].Algo)
303 -
304 - case "sum_metric_delta":
305 - // Find the chart for the delta sum metric
306 - var sumChart *ChartDefinition
307 - for _, chart := range charts {
308 - if chart.Context == "test.sum" {
309 - sumChart = chart
310 - break
311 - }
312 - }
313 - require.NotNil(t, sumChart, "Sum chart should exist")
314 - assert.Equal(t, "Test Sum", sumChart.Title)
315 - assert.Equal(t, "count", sumChart.Units)
316 - assert.Equal(t, "test", sumChart.Family)
317 - assert.Equal(t, "line", sumChart.Type)
318 - assert.Len(t, sumChart.Dimensions, 1)
319 - assert.Equal(t, 100.0, sumChart.Dimensions[0].Value)
320 - assert.Equal(t, "incremental", sumChart.Dimensions[0].Algo, "Delta temporality should use incremental algorithm")
321 -
322 - case "sum_metric_cumulative":
323 - // Find the chart for the cumulative sum metric
324 - var sumChart *ChartDefinition
325 - for _, chart := range charts {
326 - if chart.Context == "test.sum" {
327 - sumChart = chart
328 - break
329 - }
330 - }
331 - require.NotNil(t, sumChart, "Sum chart should exist")
332 - assert.Equal(t, "Test Sum", sumChart.Title)
333 - assert.Equal(t, "count", sumChart.Units)
334 - assert.Equal(t, "test", sumChart.Family)
335 - assert.Equal(t, "line", sumChart.Type)
336 - assert.Len(t, sumChart.Dimensions, 1)
337 - assert.Equal(t, 100.0, sumChart.Dimensions[0].Value)
338 - assert.Equal(t, "absolute", sumChart.Dimensions[0].Algo, "Cumulative temporality should use absolute algorithm")
339 -
340 - case "histogram_metric":
341 - // Check count chart
342 - var countChart *ChartDefinition
343 - for _, chart := range charts {
344 - if chart.Context == "test.histogram.count" {
345 - countChart = chart
346 - break
347 - }
348 - }
349 - require.NotNil(t, countChart, "Histogram count chart should exist")
350 - assert.Equal(t, "Test Histogram (Count)", countChart.Title)
351 - assert.Equal(t, "count", countChart.Units)
352 - assert.Equal(t, "line", countChart.Type)
353 - assert.Len(t, countChart.Dimensions, 1)
354 - assert.Equal(t, 30.0, countChart.Dimensions[0].Value)
355 - assert.Equal(t, "absolute", countChart.Dimensions[0].Algo)
356 -
357 - // Check sum chart
358 - var sumChart *ChartDefinition
359 - for _, chart := range charts {
360 - if chart.Context == "test.histogram.sum" {
361 - sumChart = chart
362 - break
363 - }
364 - }
365 - require.NotNil(t, sumChart, "Histogram sum chart should exist")
366 - assert.Equal(t, "Test Histogram (Sum)", sumChart.Title)
367 - assert.Equal(t, "ms", sumChart.Units)
368 - assert.Equal(t, "line", sumChart.Type)
369 - assert.Len(t, sumChart.Dimensions, 1)
370 - assert.Equal(t, 200.0, sumChart.Dimensions[0].Value)
371 -
372 - // Check buckets chart
373 - var bucketsChart *ChartDefinition
374 - for _, chart := range charts {
375 - if chart.Context == "test.histogram.buckets" {
376 - bucketsChart = chart
377 - break
378 - }
379 - }
380 - require.NotNil(t, bucketsChart, "Histogram buckets chart should exist")
381 - assert.Equal(t, "Test Histogram (Buckets)", bucketsChart.Title)
382 - assert.Equal(t, "count", bucketsChart.Units)
383 - assert.Equal(t, "stacked", bucketsChart.Type)
384 - assert.Len(t, bucketsChart.Dimensions, 3)
385 -
386 - // Verify bucket values (we don't know exact order, so check all values are present)
387 - bucketValues := []float64{10.0, 15.0, 5.0}
388 - for _, dim := range bucketsChart.Dimensions {
389 - assert.Contains(t, bucketValues, dim.Value)
390 - }
391 -
392 - case "exponential_histogram_metric":
393 - // Check count chart
394 - var countChart *ChartDefinition
395 - for _, chart := range charts {
396 - if chart.Context == "test.exponential_histogram.count" {
397 - countChart = chart
398 - break
399 - }
400 - }
401 - require.NotNil(t, countChart, "Exponential histogram count chart should exist")
402 - assert.Equal(t, "Test Exponential Histogram (Count)", countChart.Title)
403 - assert.Equal(t, "count", countChart.Units)
404 - assert.Equal(t, "line", countChart.Type)
405 - assert.Len(t, countChart.Dimensions, 1)
406 - assert.Equal(t, 30.0, countChart.Dimensions[0].Value)
407 - assert.Equal(t, "incremental", countChart.Dimensions[0].Algo, "Delta temporality should use incremental algorithm")
408 -
409 - // Check sum chart
410 - var sumChart *ChartDefinition
411 - for _, chart := range charts {
412 - if chart.Context == "test.exponential_histogram.sum" {
413 - sumChart = chart
414 - break
415 - }
416 - }
417 - require.NotNil(t, sumChart, "Exponential histogram sum chart should exist")
418 - assert.Equal(t, "Test Exponential Histogram (Sum)", sumChart.Title)
419 - assert.Equal(t, "ms", sumChart.Units)
420 - assert.Equal(t, "line", sumChart.Type)
421 - assert.Len(t, sumChart.Dimensions, 1)
422 - assert.Equal(t, 200.0, sumChart.Dimensions[0].Value)
423 -
424 - // Check distribution chart
425 - var distChart *ChartDefinition
426 - for _, chart := range charts {
427 - if chart.Context == "test.exponential_histogram.distribution" {
428 - distChart = chart
429 - break
430 - }
431 - }
432 - require.NotNil(t, distChart, "Exponential histogram distribution chart should exist")
433 - assert.Equal(t, "Test Exponential Histogram (Distribution)", distChart.Title)
434 - assert.Equal(t, "count", distChart.Units)
435 - assert.Equal(t, "stacked", distChart.Type)
436 - assert.Len(t, distChart.Dimensions, 3)
437 -
438 - // Find the dimensions for positive, zero, and negative values
439 - positiveValue := 0.0
440 - zeroValue := 0.0
441 - negativeValue := 0.0
442 -
443 - for _, dim := range distChart.Dimensions {
444 - if dim.Name == "Positive Values" {
445 - positiveValue = dim.Value
446 - } else if dim.Name == "Zero Values" {
447 - zeroValue = dim.Value
448 - } else if dim.Name == "Negative Values" {
449 - negativeValue = dim.Value
450 - }
451 - }
452 -
453 - assert.Equal(t, 15.0, positiveValue, "Positive bucket count should sum to 15")
454 - assert.Equal(t, 5.0, zeroValue, "Zero bucket count should be 5")
455 - assert.Equal(t, 10.0, negativeValue, "Negative bucket count should sum to 10")
456 -
457 - case "summary_metric":
458 - // Check count chart
459 - var countChart *ChartDefinition
460 - for _, chart := range charts {
461 - if chart.Context == "test.summary.count" {
462 - countChart = chart
463 - break
464 - }
465 - }
466 - require.NotNil(t, countChart, "Summary count chart should exist")
467 - assert.Equal(t, "Test Summary (Count)", countChart.Title)
468 - assert.Equal(t, "count", countChart.Units)
469 - assert.Equal(t, "line", countChart.Type)
470 - assert.Len(t, countChart.Dimensions, 1)
471 - assert.Equal(t, 100.0, countChart.Dimensions[0].Value)
472 -
473 - // Check sum chart
474 - var sumChart *ChartDefinition
475 - for _, chart := range charts {
476 - if chart.Context == "test.summary.sum" {
477 - sumChart = chart
478 - break
479 - }
480 - }
481 - require.NotNil(t, sumChart, "Summary sum chart should exist")
482 - assert.Equal(t, "Test Summary (Sum)", sumChart.Title)
483 - assert.Equal(t, "ms", sumChart.Units)
484 - assert.Equal(t, "line", sumChart.Type)
485 - assert.Len(t, sumChart.Dimensions, 1)
486 - assert.Equal(t, 5000.0, sumChart.Dimensions[0].Value)
487 -
488 - // Check quantiles chart
489 - var quantilesChart *ChartDefinition
490 - for _, chart := range charts {
491 - if chart.Context == "test.summary.quantiles" {
492 - quantilesChart = chart
493 - break
494 - }
495 - }
496 - require.NotNil(t, quantilesChart, "Summary quantiles chart should exist")
497 - assert.Equal(t, "Test Summary (Quantiles)", quantilesChart.Title)
498 - assert.Equal(t, "ms", quantilesChart.Units)
499 - assert.Equal(t, "line", quantilesChart.Type)
500 - assert.Len(t, quantilesChart.Dimensions, 5)
501 -
502 - // Find dimensions for min, max, and p50
503 - var minValue, maxValue, p50Value float64
504 - for _, dim := range quantilesChart.Dimensions {
505 - if dim.Name == "min" {
506 - minValue = dim.Value
507 - } else if dim.Name == "max" {
508 - maxValue = dim.Value
509 - } else if dim.Name == "p50" {
510 - p50Value = dim.Value
511 - }
512 - }
513 -
514 - assert.Equal(t, 1.0, minValue, "Minimum (p0) quantile should be 1.0")
515 - assert.Equal(t, 100.0, maxValue, "Maximum (p100) quantile should be 100.0")
516 - assert.Equal(t, 5.0, p50Value, "p50 quantile should be 5.0")
517 -
518 - case "multiple_data_points_by_attribute":
519 - assert.Len(t, charts, 2, "Should have two charts for the multiple data points test")
520 -
521 - // Collect all dimension values to ensure we have both 100.0 and 200.0
522 - values := make([]float64, 0, 2)
523 - for _, chart := range charts {
524 - assert.Equal(t, "test.gauge.multi", chart.Context, "Chart context should match metric name")
525 - assert.Equal(t, "Test Gauge with Multiple Points", chart.Title)
526 - assert.Equal(t, "bytes", chart.Units)
527 -
528 - for _, dim := range chart.Dimensions {
529 - values = append(values, dim.Value)
530 - }
531 - }
532 -
533 - assert.Contains(t, values, 100.0, "Should have a dimension with value 100.0")
534 - assert.Contains(t, values, 200.0, "Should have a dimension with value 200.0")
535 -
536 - case "staleness_marker":
537 - assert.Len(t, charts, 1, "Should have one chart for the staleness marker test")
538 -
539 - for _, chart := range charts {
540 - assert.Equal(t, "test.gauge.stale", chart.Context)
541 - assert.Equal(t, "Test Gauge with Staleness Marker", chart.Title)
542 - assert.Len(t, chart.Dimensions, 1, "Should have one dimension (non-stale point)")
543 - assert.Equal(t, 100.0, chart.Dimensions[0].Value, "Dimension value should be 100.0 (from non-stale point)")
544 - }
545 -
546 - case "resource_and_datapoint_attributes_as_labels":
547 - assert.Len(t, charts, 1, "Should have one chart for the labels test")
548 -
549 - for _, chart := range charts {
550 - assert.Equal(t, "test.labels", chart.Context)
551 - assert.Equal(t, "test-service_test", chart.Family, "Family should include service name")
552 -
553 - // Check for expected labels
554 - labelMap := make(map[string]string)
555 - for _, label := range chart.Labels {
556 - labelMap[label.Name] = label.Value
557 - }
558 -
559 - assert.Equal(t, "production", labelMap["deployment.environment"], "Should have deployment.environment label")
560 - assert.Equal(t, "test-service", labelMap["service.name"], "Should have service.name label")
561 - assert.Equal(t, "host1", labelMap["host"], "Should have host label")
562 - assert.Equal(t, "us-west", labelMap["region"], "Should have region label")
563 -
564 - // Check dimension
565 - assert.Len(t, chart.Dimensions, 1)
566 - assert.Equal(t, 42.0, chart.Dimensions[0].Value)
567 - }
568 - }
569 - })
570 - }
571 -}
572 -
573 -// Helper functions tests
574 -
575 -func TestHelperFunctions(t *testing.T) {
576 - // Test sanitizeID
577 - t.Run("sanitizeID", func(t *testing.T) {
578 - tests := map[string]struct {
579 - input string
580 - expected string
581 - }{
582 - "valid_id": {"valid_id", "valid_id"},
583 - "spaces": {"test metric", "test_metric"},
584 - "special_chars": {"test/metric:value", "test_metric_value"},
585 - "starts_with_number": {"123test", "n_123test"},
586 - "multiple_special_chars": {"test@metric#value", "test_metric_value"},
587 - "empty_string": {"", "unknown"},
588 - "very_long_id": {strings.Repeat("a", 150), strings.Repeat("a", 150)},
589 - }
590 -
591 - for name, tt := range tests {
592 - t.Run(name, func(t *testing.T) {
593 - result := sanitizeID(tt.input)
594 - assert.Equal(t, tt.expected, result)
595 - })
596 - }
597 - })
598 -
599 - // Test generateChartID
600 - t.Run("generateChartID", func(t *testing.T) {
601 - // Test that long metric names are truncated in the chart ID
602 - veryLongName := strings.Repeat("abcdefghij", 15) // 150 characters
603 - attrHash := "testhash"
604 - chartID := generateChartID(veryLongName, attrHash)
605 -
606 - // Chart ID should be truncated to maxChartIDLength
607 - assert.LessOrEqual(t, len(chartID), maxChartIDLength, "Chart ID should not exceed maxChartIDLength")
608 -
609 - // Chart ID should still end with the attribute hash
610 - assert.True(t, strings.HasSuffix(chartID, attrHash), "Chart ID should end with the attribute hash")
611 - })
612 -
613 - // Test attributesHash
614 - t.Run("attributesHash", func(t *testing.T) {
615 - // Test consistent hashing with different attribute orders
616 - attrs1 := pcommon.NewMap()
617 - attrs1.PutStr("a", "1")
618 - attrs1.PutStr("b", "2")
619 -
620 - attrs2 := pcommon.NewMap()
621 - attrs2.PutStr("b", "2")
622 - attrs2.PutStr("a", "1")
623 -
624 - hash1 := attributesHash(attrs1)
625 - hash2 := attributesHash(attrs2)
626 -
627 - assert.Equal(t, hash1, hash2, "Hash should be consistent regardless of attribute order")
628 -
629 - // Test empty attributes
630 - emptyAttrs := pcommon.NewMap()
631 - emptyHash := attributesHash(emptyAttrs)
632 - assert.Equal(t, "default", emptyHash, "Empty attributes should hash to 'default'")
633 - })
634 -
635 - // Test getFamily
636 - t.Run("getFamily", func(t *testing.T) {
637 - // Test with service name
638 - resourceAttrs := pcommon.NewMap()
639 - resourceAttrs.PutStr("service.name", "test-service")
640 -
641 - family := getFamily("test.metric", resourceAttrs)
642 - assert.Equal(t, "test-service_test", family, "Family should include service name")
643 -
644 - // Test without service name but with service namespace
645 - resourceAttrs = pcommon.NewMap()
646 - resourceAttrs.PutStr("service.namespace", "test-namespace")
647 -
648 - family = getFamily("test.metric", resourceAttrs)
649 - assert.Equal(t, "test_namespace_test", family, "Family should include service namespace")
650 -
651 - // Test without service name or namespace
652 - resourceAttrs = pcommon.NewMap()
653 -
654 - family = getFamily("test.metric", resourceAttrs)
655 - assert.Equal(t, "test", family, "Family should be based on metric name prefix")
656 - })
657 -}
src/go/otel-collector/exporter/netdataexporter/doc.go deleted
-3
@@ -1,3 +0,0 @@
1 -//go:generate mdatagen metadata.yaml
2 -
3 -package netdataexporter
src/go/otel-collector/exporter/netdataexporter/exporter.go deleted
-108
@@ -1,108 +0,0 @@
1 -package netdataexporter
2 -
3 -import (
4 - "context"
5 -
6 - "go.opentelemetry.io/collector/component"
7 - "go.opentelemetry.io/collector/pdata/pmetric"
8 - "go.uber.org/zap"
9 -)
10 -
11 -type netdataExporter struct {
12 - log *zap.Logger
13 - conf *Config
14 -
15 - api *netdataAPI
16 -
17 - //MaxLabelCount int // Maximum number of labels to include per chart (0 = unlimited)
18 - //UseShortIDs bool // Use shortened IDs for better performance
19 - //GroupSimilarPoints bool // Group similar data points into a single dimension
20 - //
21 - //// State management
22 - //charts map[string]*ChartDefinition // Map to store and track charts across iterations
23 - //chartsMu sync.RWMutex // Mutex to protect the charts map during concurrent access
24 - //lastUpdate time.Time // Track the last update time
25 -
26 - charts map[string]*ChartDefinition
27 -}
28 -
29 -func newNetdataExporter(cfg component.Config, logger *zap.Logger) *netdataExporter {
30 - return &netdataExporter{
31 - log: logger,
32 - conf: cfg.(*Config),
33 - api: newNetdataStdoutApi(),
34 - }
35 -}
36 -
37 -func (e *netdataExporter) consumeMetrics(ctx context.Context, pm pmetric.Metrics) error {
38 - e.convert(pm)
39 - e.sendCharts()
40 - e.updateCharts(0)
41 -
42 - return nil
43 -}
44 -
45 -func (e *netdataExporter) Start(_ context.Context, _ component.Host) error {
46 - return nil
47 -}
48 -
49 -func (e *netdataExporter) Shutdown(context.Context) error {
50 - return nil
51 -}
52 -
53 -func (e *netdataExporter) sendCharts() {
54 - for _, chart := range e.charts {
55 - if chart.IsNew {
56 - opts := ChartOpts{
57 - TypeID: "",
58 - ID: chart.ID,
59 - Title: chart.Title,
60 - Units: chart.Units,
61 - Family: chart.Family,
62 - Context: chart.Context,
63 - ChartType: chart.Type,
64 - Priority: 1000,
65 - UpdateEvery: 1,
66 - Options: chart.Options,
67 - Plugin: "otel",
68 - Module: "metrics",
69 - }
70 -
71 - e.api.chart(opts)
72 - for _, label := range chart.Labels {
73 - e.api.clabel(label.Name, label.Value)
74 - }
75 - e.api.clabelcommit()
76 -
77 - for _, dim := range chart.Dimensions {
78 - dimOpts := DimensionOpts{
79 - ID: dim.ID,
80 - Name: dim.Name,
81 - Algorithm: dim.Algo,
82 - Multiplier: 1,
83 - Divisor: 1,
84 - Options: "",
85 - }
86 - e.api.dimension(dimOpts)
87 - }
88 -
89 - chart.IsNew = false
90 - }
91 - }
92 -}
93 -
94 -func (e *netdataExporter) updateCharts(msSince int) {
95 - for id, chart := range e.charts {
96 - if len(chart.Dimensions) == 0 {
97 - continue
98 - }
99 -
100 - e.api.begin(id, msSince)
101 -
102 - for _, dim := range chart.Dimensions {
103 - value := int64(dim.Value)
104 - e.api.set(dim.ID, value)
105 - }
106 - e.api.end()
107 - }
108 -}
src/go/otel-collector/exporter/netdataexporter/factory.go deleted
-39
@@ -1,39 +0,0 @@
1 -package netdataexporter
2 -
3 -import (
4 - "context"
5 -
6 - "go.opentelemetry.io/collector/component"
7 - "go.opentelemetry.io/collector/consumer"
8 - "go.opentelemetry.io/collector/exporter"
9 - "go.opentelemetry.io/collector/exporter/exporterhelper"
10 - "go.opentelemetry.io/collector/exporter/xexporter"
11 -
12 - "github.com/netdata/netdata/otel-collector/exporter/netdataexporter/internal/metadata"
13 -)
14 -
15 -func NewFactory() exporter.Factory {
16 - return xexporter.NewFactory(
17 - metadata.Type,
18 - createDefaultConfig,
19 - xexporter.WithMetrics(createMetricsExporter, metadata.MetricsStability),
20 - )
21 -}
22 -
23 -func createDefaultConfig() component.Config {
24 - return &Config{}
25 -}
26 -
27 -func createMetricsExporter(ctx context.Context, set exporter.Settings, cfg component.Config) (exporter.Metrics, error) {
28 - exp := newNetdataExporter(cfg, set.Logger)
29 -
30 - return exporterhelper.NewMetrics(
31 - ctx,
32 - set,
33 - cfg,
34 - exp.consumeMetrics,
35 - exporterhelper.WithStart(exp.Start),
36 - exporterhelper.WithShutdown(exp.Shutdown),
37 - exporterhelper.WithCapabilities(consumer.Capabilities{MutatesData: false}),
38 - )
39 -}
src/go/otel-collector/exporter/netdataexporter/generated_component_test.go deleted
-138
@@ -1,138 +0,0 @@
1 -// Code generated by mdatagen. DO NOT EDIT.
2 -
3 -package netdataexporter
4 -
5 -import (
6 - "context"
7 - "testing"
8 - "time"
9 -
10 - "github.com/stretchr/testify/require"
11 - "go.opentelemetry.io/collector/component"
12 - "go.opentelemetry.io/collector/component/componenttest"
13 - "go.opentelemetry.io/collector/confmap/confmaptest"
14 - "go.opentelemetry.io/collector/exporter"
15 - "go.opentelemetry.io/collector/exporter/exportertest"
16 - "go.opentelemetry.io/collector/pdata/pcommon"
17 - "go.opentelemetry.io/collector/pdata/plog"
18 - "go.opentelemetry.io/collector/pdata/pmetric"
19 - "go.opentelemetry.io/collector/pdata/ptrace"
20 -)
21 -
22 -var typ = component.MustNewType("netdataexporter")
23 -
24 -func TestComponentFactoryType(t *testing.T) {
25 - require.Equal(t, typ, NewFactory().Type())
26 -}
27 -
28 -func TestComponentConfigStruct(t *testing.T) {
29 - require.NoError(t, componenttest.CheckConfigStruct(NewFactory().CreateDefaultConfig()))
30 -}
31 -
32 -func TestComponentLifecycle(t *testing.T) {
33 - factory := NewFactory()
34 -
35 - tests := []struct {
36 - createFn func(ctx context.Context, set exporter.Settings, cfg component.Config) (component.Component, error)
37 - name string
38 - }{
39 -
40 - {
41 - name: "metrics",
42 - createFn: func(ctx context.Context, set exporter.Settings, cfg component.Config) (component.Component, error) {
43 - return factory.CreateMetrics(ctx, set, cfg)
44 - },
45 - },
46 - }
47 -
48 - cm, err := confmaptest.LoadConf("metadata.yaml")
49 - require.NoError(t, err)
50 - cfg := factory.CreateDefaultConfig()
51 - sub, err := cm.Sub("tests::config")
52 - require.NoError(t, err)
53 - require.NoError(t, sub.Unmarshal(&cfg))
54 -
55 - for _, tt := range tests {
56 - t.Run(tt.name+"-shutdown", func(t *testing.T) {
57 - c, err := tt.createFn(context.Background(), exportertest.NewNopSettings(typ), cfg)
58 - require.NoError(t, err)
59 - err = c.Shutdown(context.Background())
60 - require.NoError(t, err)
61 - })
62 - t.Run(tt.name+"-lifecycle", func(t *testing.T) {
63 - c, err := tt.createFn(context.Background(), exportertest.NewNopSettings(typ), cfg)
64 - require.NoError(t, err)
65 - host := componenttest.NewNopHost()
66 - err = c.Start(context.Background(), host)
67 - require.NoError(t, err)
68 - require.NotPanics(t, func() {
69 - switch tt.name {
70 - case "logs":
71 - e, ok := c.(exporter.Logs)
72 - require.True(t, ok)
73 - logs := generateLifecycleTestLogs()
74 - if !e.Capabilities().MutatesData {
75 - logs.MarkReadOnly()
76 - }
77 - err = e.ConsumeLogs(context.Background(), logs)
78 - case "metrics":
79 - e, ok := c.(exporter.Metrics)
80 - require.True(t, ok)
81 - metrics := generateLifecycleTestMetrics()
82 - if !e.Capabilities().MutatesData {
83 - metrics.MarkReadOnly()
84 - }
85 - err = e.ConsumeMetrics(context.Background(), metrics)
86 - case "traces":
87 - e, ok := c.(exporter.Traces)
88 - require.True(t, ok)
89 - traces := generateLifecycleTestTraces()
90 - if !e.Capabilities().MutatesData {
91 - traces.MarkReadOnly()
92 - }
93 - err = e.ConsumeTraces(context.Background(), traces)
94 - }
95 - })
96 -
97 - require.NoError(t, err)
98 -
99 - err = c.Shutdown(context.Background())
100 - require.NoError(t, err)
101 - })
102 - }
103 -}
104 -
105 -func generateLifecycleTestLogs() plog.Logs {
106 - logs := plog.NewLogs()
107 - rl := logs.ResourceLogs().AppendEmpty()
108 - rl.Resource().Attributes().PutStr("resource", "R1")
109 - l := rl.ScopeLogs().AppendEmpty().LogRecords().AppendEmpty()
110 - l.Body().SetStr("test log message")
111 - l.SetTimestamp(pcommon.NewTimestampFromTime(time.Now()))
112 - return logs
113 -}
114 -
115 -func generateLifecycleTestMetrics() pmetric.Metrics {
116 - metrics := pmetric.NewMetrics()
117 - rm := metrics.ResourceMetrics().AppendEmpty()
118 - rm.Resource().Attributes().PutStr("resource", "R1")
119 - m := rm.ScopeMetrics().AppendEmpty().Metrics().AppendEmpty()
120 - m.SetName("test_metric")
121 - dp := m.SetEmptyGauge().DataPoints().AppendEmpty()
122 - dp.Attributes().PutStr("test_attr", "value_1")
123 - dp.SetIntValue(123)
124 - dp.SetTimestamp(pcommon.NewTimestampFromTime(time.Now()))
125 - return metrics
126 -}
127 -
128 -func generateLifecycleTestTraces() ptrace.Traces {
129 - traces := ptrace.NewTraces()
130 - rs := traces.ResourceSpans().AppendEmpty()
131 - rs.Resource().Attributes().PutStr("resource", "R1")
132 - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty()
133 - span.Attributes().PutStr("test_attr", "value_1")
134 - span.SetName("test_span")
135 - span.SetStartTimestamp(pcommon.NewTimestampFromTime(time.Now().Add(-1 * time.Second)))
136 - span.SetEndTimestamp(pcommon.NewTimestampFromTime(time.Now()))
137 - return traces
138 -}
src/go/otel-collector/exporter/netdataexporter/generated_package_test.go deleted
-12
@@ -1,12 +0,0 @@
1 -// Code generated by mdatagen. DO NOT EDIT.
2 -
3 -package netdataexporter
4 -
5 -import (
6 - "go.uber.org/goleak"
7 - "testing"
8 -)
9 -
10 -func TestMain(m *testing.M) {
11 - goleak.VerifyTestMain(m)
12 -}
src/go/otel-collector/exporter/netdataexporter/go.mod deleted
-73
@@ -1,73 +0,0 @@
1 -module github.com/netdata/netdata/otel-collector/exporter/netdataexporter
2 -
3 -go 1.24.0
4 -
5 -require (
6 - github.com/stretchr/testify v1.11.1
7 - go.opentelemetry.io/collector/component v1.43.0
8 - go.opentelemetry.io/collector/component/componenttest v0.137.0
9 - go.opentelemetry.io/collector/confmap v1.43.0
10 - go.opentelemetry.io/collector/consumer v1.43.0
11 - go.opentelemetry.io/collector/exporter v1.43.0
12 - go.opentelemetry.io/collector/exporter/exporterhelper v0.137.0
13 - go.opentelemetry.io/collector/exporter/exportertest v0.137.0
14 - go.opentelemetry.io/collector/exporter/xexporter v0.137.0
15 - go.opentelemetry.io/collector/pdata v1.43.0
16 - go.uber.org/goleak v1.3.0
17 - go.uber.org/zap v1.27.0
18 -)
19 -
20 -require (
21 - github.com/cenkalti/backoff/v5 v5.0.3 // indirect
22 - github.com/davecgh/go-spew v1.1.1 // indirect
23 - github.com/go-logr/logr v1.4.3 // indirect
24 - github.com/go-logr/stdr v1.2.2 // indirect
25 - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
26 - github.com/gobwas/glob v0.2.3 // indirect
27 - github.com/gogo/protobuf v1.3.2 // indirect
28 - github.com/google/uuid v1.6.0 // indirect
29 - github.com/hashicorp/go-version v1.7.0 // indirect
30 - github.com/json-iterator/go v1.1.12 // indirect
31 - github.com/knadh/koanf/maps v0.1.2 // indirect
32 - github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
33 - github.com/knadh/koanf/v2 v2.3.0 // indirect
34 - github.com/mitchellh/copystructure v1.2.0 // indirect
35 - github.com/mitchellh/reflectwalk v1.0.2 // indirect
36 - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
37 - github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
38 - github.com/pmezard/go-difflib v1.0.0 // indirect
39 - go.opentelemetry.io/auto/sdk v1.2.1 // indirect
40 - go.opentelemetry.io/collector/client v1.43.0 // indirect
41 - go.opentelemetry.io/collector/config/configoptional v1.43.0 // indirect
42 - go.opentelemetry.io/collector/config/configretry v1.43.0 // indirect
43 - go.opentelemetry.io/collector/confmap/xconfmap v0.137.0 // indirect
44 - go.opentelemetry.io/collector/consumer/consumererror v0.137.0 // indirect
45 - go.opentelemetry.io/collector/consumer/consumertest v0.137.0 // indirect
46 - go.opentelemetry.io/collector/consumer/xconsumer v0.137.0 // indirect
47 - go.opentelemetry.io/collector/extension v1.43.0 // indirect
48 - go.opentelemetry.io/collector/extension/xextension v0.137.0 // indirect
49 - go.opentelemetry.io/collector/featuregate v1.43.0 // indirect
50 - go.opentelemetry.io/collector/internal/telemetry v0.137.0 // indirect
51 - go.opentelemetry.io/collector/pdata/pprofile v0.137.0 // indirect
52 - go.opentelemetry.io/collector/pdata/xpdata v0.137.0 // indirect
53 - go.opentelemetry.io/collector/pipeline v1.43.0 // indirect
54 - go.opentelemetry.io/collector/receiver v1.43.0 // indirect
55 - go.opentelemetry.io/collector/receiver/receivertest v0.137.0 // indirect
56 - go.opentelemetry.io/collector/receiver/xreceiver v0.137.0 // indirect
57 - go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 // indirect
58 - go.opentelemetry.io/otel v1.38.0 // indirect
59 - go.opentelemetry.io/otel/log v0.14.0 // indirect
60 - go.opentelemetry.io/otel/metric v1.38.0 // indirect
61 - go.opentelemetry.io/otel/sdk v1.38.0 // indirect
62 - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
63 - go.opentelemetry.io/otel/trace v1.38.0 // indirect
64 - go.uber.org/multierr v1.11.0 // indirect
65 - go.yaml.in/yaml/v3 v3.0.4 // indirect
66 - golang.org/x/net v0.46.0 // indirect
67 - golang.org/x/sys v0.37.0 // indirect
68 - golang.org/x/text v0.30.0 // indirect
69 - google.golang.org/genproto/googleapis/rpc v0.0.0-20251007200510-49b9836ed3ff // indirect
70 - google.golang.org/grpc v1.76.0 // indirect
71 - google.golang.org/protobuf v1.36.10 // indirect
72 - gopkg.in/yaml.v3 v3.0.1 // indirect
73 -)
src/go/otel-collector/exporter/netdataexporter/go.sum deleted
-191
@@ -1,191 +0,0 @@
1 -github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
2 -github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
3 -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4 -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
5 -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6 -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
7 -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
8 -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
9 -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
10 -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
11 -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
12 -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
13 -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
14 -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
15 -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
16 -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
17 -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
18 -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
19 -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
20 -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
21 -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
22 -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
23 -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
24 -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
25 -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
26 -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
27 -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
28 -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
29 -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
30 -github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo=
31 -github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
32 -github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE=
33 -github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A=
34 -github.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM=
35 -github.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28=
36 -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
37 -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
38 -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
39 -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
40 -github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
41 -github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
42 -github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
43 -github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
44 -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
45 -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
46 -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
47 -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
48 -github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
49 -github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
50 -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
51 -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
52 -github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
53 -github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
54 -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
55 -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
56 -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
57 -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
58 -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
59 -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
60 -go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
61 -go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
62 -go.opentelemetry.io/collector/client v1.43.0 h1:uWAjq2AHoKg1Yz4/NKYoDPKhU6jJSSWX9zIKdGLCOlg=
63 -go.opentelemetry.io/collector/client v1.43.0/go.mod h1:9EQOLvyRdozYDKOC7XHIapKT2N6wGWHqgbDply/uRj4=
64 -go.opentelemetry.io/collector/component v1.43.0 h1:9dyOmV0UuIhrNSASMeDH125jhfv7+FhWMq0HtNHHCs8=
65 -go.opentelemetry.io/collector/component v1.43.0/go.mod h1:Pw3qM5HhgnSMpebNRUiiJuEiXxZyHq83vl7wXqxD8hU=
66 -go.opentelemetry.io/collector/component/componenttest v0.137.0 h1:QC9MZsYyzQqN9qMlleJb78wf7FeCjbr4jLeCuNlKHLU=
67 -go.opentelemetry.io/collector/component/componenttest v0.137.0/go.mod h1:JuiX9pv7qE5G8keihhjM66LeidryEnziPND0sXuK9PQ=
68 -go.opentelemetry.io/collector/config/configoptional v1.43.0 h1:u/MCeLUawXINEi05VdRuBRQ3wivEltxTjJqnL1eww4w=
69 -go.opentelemetry.io/collector/config/configoptional v1.43.0/go.mod h1:vdhEmJCpL4nQx2fETr3Bvg9Uy14IwThxL5/g8Mvo/A8=
70 -go.opentelemetry.io/collector/config/configretry v1.43.0 h1:Va5pDNL0TOzqjLdJZ4xxQN9EggMSGVmxXBa+M6UEG30=
71 -go.opentelemetry.io/collector/config/configretry v1.43.0/go.mod h1:ZSTYqAJCq4qf+/4DGoIxCElDIl5yHt8XxEbcnpWBbMM=
72 -go.opentelemetry.io/collector/confmap v1.43.0 h1:QVAnbS7A+2Ra61xsuG355vhlW6uOMaKWysrwLQzDUz4=
73 -go.opentelemetry.io/collector/confmap v1.43.0/go.mod h1:N5GZpFCmwD1GynDu3IWaZW5Ycfc/7YxSU0q1/E3vLdg=
74 -go.opentelemetry.io/collector/confmap/xconfmap v0.137.0 h1:IKzD6w4YuvBi6GvxZfhz7SJR6GR1UpSQRuxtx20/+9U=
75 -go.opentelemetry.io/collector/confmap/xconfmap v0.137.0/go.mod h1:psXdQr13pVrCqNPdoER2QZZorvONAR5ZUEHURe4POh4=
76 -go.opentelemetry.io/collector/consumer v1.43.0 h1:51pfN5h6PLlaBwGPtyHn6BdK0DgtVGRV0UYRPbbscbs=
77 -go.opentelemetry.io/collector/consumer v1.43.0/go.mod h1:v3J2g+6IwOPbLsnzL9cQfvgpmmsZt1YS7aXSNDFmJfk=
78 -go.opentelemetry.io/collector/consumer/consumererror v0.137.0 h1:4HgYX6vVmaF17RRRtJDpR8EuWmLAv6JdKYG8slDDa+g=
79 -go.opentelemetry.io/collector/consumer/consumererror v0.137.0/go.mod h1:muYN3UZ/43YHpDpQRVvCj0Rhpt/YjoPAF/BO63cPSwk=
80 -go.opentelemetry.io/collector/consumer/consumertest v0.137.0 h1:tkqBk/DmJcrkRvHwNdDwvdiWfqyS6ymGgr9eyn6Vy6A=
81 -go.opentelemetry.io/collector/consumer/consumertest v0.137.0/go.mod h1:6bKAlEgrAZ3NSn7ULLFZQMQtlW2xJlvVWkzIaGprucg=
82 -go.opentelemetry.io/collector/consumer/xconsumer v0.137.0 h1:p3tkV3O9bL3bZl3RN2wmoxl22f8B8eMomKUqz656OPY=
83 -go.opentelemetry.io/collector/consumer/xconsumer v0.137.0/go.mod h1:N+nRnP0ga4Scu8Ew87F+kxVajE/eGjRLbWC9H+elN5Q=
84 -go.opentelemetry.io/collector/exporter v1.43.0 h1:FYQ/bhOOiLcmIFvDAUvqfzHmZSvKkTrIFyYprPw3xug=
85 -go.opentelemetry.io/collector/exporter v1.43.0/go.mod h1:lUB2OSGrRyD5PSXU0rF9gWcUYCGublBdnCV5hKlG+z8=
86 -go.opentelemetry.io/collector/exporter/exporterhelper v0.137.0 h1:ffiZjBJvzgPYJpOltwIpvTCF8zg1VPxsoP6aW4VTDuQ=
87 -go.opentelemetry.io/collector/exporter/exporterhelper v0.137.0/go.mod h1:osf2K/HkbdUU7EFigLhxMmz2r5MX/74vYC2RrBDURrc=
88 -go.opentelemetry.io/collector/exporter/exportertest v0.137.0 h1:JesnY7M87UWE/gRsVUgskX95QCL/S4j1ARQTVHH4ggg=
89 -go.opentelemetry.io/collector/exporter/exportertest v0.137.0/go.mod h1:6UxHqO5IyMKL3ehlE3UNpFupIyGc5BBj7xzmPoDImOI=
90 -go.opentelemetry.io/collector/exporter/xexporter v0.137.0 h1:2fSmBDB+tuFoYKJSHbR/1nJIeO+LvvrjdOYEODKuhdo=
91 -go.opentelemetry.io/collector/exporter/xexporter v0.137.0/go.mod h1:9gudRad3ijkbzcnTLE0y+CzUDtC4TaPyZQDUKB2yzVs=
92 -go.opentelemetry.io/collector/extension v1.43.0 h1:39cGAGMJIZEhhm4KbsvJJrG8AheS6wOc++ydY0Wpdp0=
93 -go.opentelemetry.io/collector/extension v1.43.0/go.mod h1:HVCPnRqx70Qn9BAmnqJt393er4l1OwcgAytLv1fSOSo=
94 -go.opentelemetry.io/collector/extension/extensiontest v0.137.0 h1:gnPF3HIOKqNk93XObt2x0WFvVfPtm76VggWe7LxgcaY=
95 -go.opentelemetry.io/collector/extension/extensiontest v0.137.0/go.mod h1:vVmKojdITYka9+iAi3aarxeMrO6kdlywKuf3d3c6lcI=
96 -go.opentelemetry.io/collector/extension/xextension v0.137.0 h1:UQ/I7D5/YmkvAV7g8yhWHY7BV31HvjGBCYduQJPyt+M=
97 -go.opentelemetry.io/collector/extension/xextension v0.137.0/go.mod h1:T2Vr5ijSNW7PavuyZyRYYxCitpUTN+f4tRUdED/rtRw=
98 -go.opentelemetry.io/collector/featuregate v1.43.0 h1:Aq8UR5qv1zNlbbkTyqv8kLJtnoQMq/sG1/jS9o1cCJI=
99 -go.opentelemetry.io/collector/featuregate v1.43.0/go.mod h1:d0tiRzVYrytB6LkcYgz2ESFTv7OktRPQe0QEQcPt1L4=
100 -go.opentelemetry.io/collector/internal/telemetry v0.137.0 h1:KlJcaBnIIn+QJzQIfA1eXbYUvHmgM7h/gLp/vjvUBMw=
101 -go.opentelemetry.io/collector/internal/telemetry v0.137.0/go.mod h1:GWOiXBZ82kMzwGMEihJ5rEo5lFL7gurfHD++5q0XtI8=
102 -go.opentelemetry.io/collector/pdata v1.43.0 h1:zVkj2hcjiMLwX+QDDNwb7iTh3LBjNXKv2qPSgj1Rzb4=
103 -go.opentelemetry.io/collector/pdata v1.43.0/go.mod h1:KsJzdDG9e5BaHlmYr0sqdSEKeEiSfKzoF+rdWU7J//w=
104 -go.opentelemetry.io/collector/pdata/pprofile v0.137.0 h1:bLVp8p8hpH81eQhhEQBkvLtS00GbnMU+ItNweBJLqZ8=
105 -go.opentelemetry.io/collector/pdata/pprofile v0.137.0/go.mod h1:QfhMf7NnG+fTuwGGB1mXgcPzcXNxEYSW6CrVouOsF7Q=
106 -go.opentelemetry.io/collector/pdata/testdata v0.137.0 h1:+oaGvbt0v7xryTX827szmyYWSAtvA0LbysEFV2nFjs0=
107 -go.opentelemetry.io/collector/pdata/testdata v0.137.0/go.mod h1:3512FJaQsZz5EBlrY46xKjzoBc0MoMcQtAqYs2NaRQM=
108 -go.opentelemetry.io/collector/pdata/xpdata v0.137.0 h1:EZvBE26Hxzk+Dv3NU7idjsS+cXbwZrwdWXGgcTxsC8g=
109 -go.opentelemetry.io/collector/pdata/xpdata v0.137.0/go.mod h1:MFbISBnECZ1m1JPc5F6LUhVIkmFkebuVk3NcpmGPtB8=
110 -go.opentelemetry.io/collector/pipeline v1.43.0 h1:IJjdqE5UCQlyVvFUUzlhSWhP4WIwpH6UyJQ9iWXpyww=
111 -go.opentelemetry.io/collector/pipeline v1.43.0/go.mod h1:xUrAqiebzYbrgxyoXSkk6/Y3oi5Sy3im2iCA51LwUAI=
112 -go.opentelemetry.io/collector/receiver v1.43.0 h1:Z/+es1SFKCwgd7mPy3Jf5KUSgy7WyypSExg4NshOwaY=
113 -go.opentelemetry.io/collector/receiver v1.43.0/go.mod h1:XhP5zl+MOMbqvvc9I5JjwULIzp7dRRUxo53EHmrl5Bc=
114 -go.opentelemetry.io/collector/receiver/receivertest v0.137.0 h1:LqlFKtThf07dFjYGLMfI2J4aio60S03gocm8CL6jOd4=
115 -go.opentelemetry.io/collector/receiver/receivertest v0.137.0/go.mod h1:bg4wfd9uq3jZfarMcqanHhQDlwbByp3GHCY7I6YO/QY=
116 -go.opentelemetry.io/collector/receiver/xreceiver v0.137.0 h1:30h6o1hI03PSc0upgwWMFRZYaVrqLaruA6r/jI1Kk/4=
117 -go.opentelemetry.io/collector/receiver/xreceiver v0.137.0/go.mod h1:kvydfp3S8PKBVXH5OgPsTSneXQ92HGyi30hSrKy1fe4=
118 -go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 h1:aBKdhLVieqvwWe9A79UHI/0vgp2t/s2euY8X59pGRlw=
119 -go.opentelemetry.io/contrib/bridges/otelzap v0.13.0/go.mod h1:SYqtxLQE7iINgh6WFuVi2AI70148B8EI35DSk0Wr8m4=
120 -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
121 -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
122 -go.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM=
123 -go.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno=
124 -go.opentelemetry.io/otel/log/logtest v0.14.0 h1:BGTqNeluJDK2uIHAY8lRqxjVAYfqgcaTbVk1n3MWe5A=
125 -go.opentelemetry.io/otel/log/logtest v0.14.0/go.mod h1:IuguGt8XVP4XA4d2oEEDMVDBBCesMg8/tSGWDjuKfoA=
126 -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
127 -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
128 -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
129 -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
130 -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
131 -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
132 -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
133 -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
134 -go.opentelemetry.io/proto/slim/otlp v1.8.0 h1:afcLwp2XOeCbGrjufT1qWyruFt+6C9g5SOuymrSPUXQ=
135 -go.opentelemetry.io/proto/slim/otlp v1.8.0/go.mod h1:Yaa5fjYm1SMCq0hG0x/87wV1MP9H5xDuG/1+AhvBcsI=
136 -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.1.0 h1:Uc+elixz922LHx5colXGi1ORbsW8DTIGM+gg+D9V7HE=
137 -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.1.0/go.mod h1:VyU6dTWBWv6h9w/+DYgSZAPMabWbPTFTuxp25sM8+s0=
138 -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.1.0 h1:i8YpvWGm/Uq1koL//bnbJ/26eV3OrKWm09+rDYo7keU=
139 -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.1.0/go.mod h1:pQ70xHY/ZVxNUBPn+qUWPl8nwai87eWdqL3M37lNi9A=
140 -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
141 -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
142 -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
143 -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
144 -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
145 -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
146 -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
147 -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
148 -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
149 -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
150 -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
151 -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
152 -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
153 -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
154 -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
155 -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
156 -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
157 -golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
158 -golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
159 -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
160 -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
161 -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
162 -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
163 -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
164 -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
165 -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
166 -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
167 -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
168 -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
169 -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
170 -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
171 -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
172 -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
173 -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
174 -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
175 -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
176 -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
177 -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
178 -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
179 -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
180 -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
181 -google.golang.org/genproto/googleapis/rpc v0.0.0-20251007200510-49b9836ed3ff h1:A90eA31Wq6HOMIQlLfzFwzqGKBTuaVztYu/g8sn+8Zc=
182 -google.golang.org/genproto/googleapis/rpc v0.0.0-20251007200510-49b9836ed3ff/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
183 -google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
184 -google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
185 -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
186 -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
187 -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
188 -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
189 -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
190 -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
191 -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
src/go/otel-collector/exporter/netdataexporter/internal/metadata/generated_status.go deleted
-16
@@ -1,16 +0,0 @@
1 -// Code generated by mdatagen. DO NOT EDIT.
2 -
3 -package metadata
4 -
5 -import (
6 - "go.opentelemetry.io/collector/component"
7 -)
8 -
9 -var (
10 - Type = component.MustNewType("netdataexporter")
11 - ScopeName = "github.com/netdata/netdata/otel-collector/exporter/netdataexporter"
12 -)
13 -
14 -const (
15 - MetricsStability = component.StabilityLevelDevelopment
16 -)
src/go/otel-collector/exporter/netdataexporter/metadata.yaml deleted
-7
@@ -1,7 +0,0 @@
1 -type: netdataexporter
2 -github_project: github.com/netdata/netdata/otel-collector/exporter/netdataexporter
3 -
4 -status:
5 - class: exporter
6 - stability:
7 - development: [metrics]
src/go/otel-collector/exporter/netdataexporter/netdataapi.go deleted
-128
@@ -1,128 +0,0 @@
1 -package netdataexporter
2 -
3 -import (
4 - "io"
5 - "os"
6 - "strconv"
7 - "sync"
8 -)
9 -
10 -type ChartOpts struct {
11 - TypeID string
12 - ID string
13 - Name string
14 - Title string
15 - Units string
16 - Family string
17 - Context string
18 - ChartType string
19 - Priority int
20 - UpdateEvery int
21 - Options string
22 - Plugin string
23 - Module string
24 -}
25 -
26 -type DimensionOpts struct {
27 - ID string
28 - Name string
29 - Algorithm string
30 - Multiplier int
31 - Divisor int
32 - Options string
33 -}
34 -
35 -type safeWriter struct {
36 - mx *sync.Mutex
37 - w io.Writer
38 -}
39 -
40 -func (w *safeWriter) Write(p []byte) (n int, err error) {
41 - w.mx.Lock()
42 - n, err = w.w.Write(p)
43 - w.mx.Unlock()
44 - return n, err
45 -}
46 -
47 -func newNetdataStdoutApi() *netdataAPI {
48 - w := &safeWriter{
49 - mx: &sync.Mutex{},
50 - w: os.Stdout,
51 - }
52 - return newNetdataApi(w)
53 -}
54 -
55 -func newNetdataApi(w io.Writer) *netdataAPI {
56 - if w == nil {
57 - panic("writer cannot be nil")
58 - }
59 - return &netdataAPI{w}
60 -}
61 -
62 -type netdataAPI struct {
63 - io.Writer
64 -}
65 -
66 -const quotes = "' '"
67 -
68 -var (
69 - newLine = []byte("\n")
70 -)
71 -
72 -func (a *netdataAPI) chart(opts ChartOpts) {
73 - _, _ = a.Write([]byte("CHART " + "'" +
74 - opts.TypeID + "." + opts.ID + quotes +
75 - opts.Name + quotes +
76 - opts.Title + quotes +
77 - opts.Units + quotes +
78 - opts.Family + quotes +
79 - opts.Context + quotes +
80 - opts.ChartType + quotes +
81 - strconv.Itoa(opts.Priority) + quotes +
82 - strconv.Itoa(opts.UpdateEvery) + quotes +
83 - opts.Options + quotes +
84 - opts.Plugin + quotes +
85 - opts.Module + "'\n"))
86 -}
87 -
88 -func (a *netdataAPI) dimension(opts DimensionOpts) {
89 - _, _ = a.Write([]byte("DIMENSION '" +
90 - opts.ID + quotes +
91 - opts.Name + quotes +
92 - opts.Algorithm + quotes +
93 - strconv.Itoa(opts.Multiplier) + quotes +
94 - strconv.Itoa(opts.Divisor) + quotes +
95 - opts.Options + "'\n"))
96 -}
97 -
98 -func (a *netdataAPI) clabel(key, value string) {
99 - _, _ = a.Write([]byte("CLABEL '" +
100 - key + quotes +
101 - value + " '0'\n"))
102 -}
103 -
104 -// CLABELCOMMIT adds labels to the chart. Should be called after one or more CLABEL.
105 -func (a *netdataAPI) clabelcommit() {
106 - _, _ = a.Write([]byte("CLABELCOMMIT\n"))
107 -}
108 -
109 -func (a *netdataAPI) begin(chartId string, msSince int) {
110 - if msSince > 0 {
111 - _, _ = a.Write([]byte("BEGIN " + "'" + chartId + "' " + strconv.Itoa(msSince) + "\n"))
112 - } else {
113 - _, _ = a.Write([]byte("BEGIN " + "'" + chartId + "'\n"))
114 - }
115 -}
116 -
117 -func (a *netdataAPI) set(dimensionId string, value int64) {
118 - _, _ = a.Write([]byte("SET '" + dimensionId + "' = " + strconv.FormatInt(value, 10) + "\n"))
119 -}
120 -
121 -// SETEMPTY sets an empty value for a dimension in the initialized chart.
122 -func (a *netdataAPI) setempty(id string) {
123 - _, _ = a.Write([]byte("SET '" + id + "' = \n"))
124 -}
125 -
126 -func (a *netdataAPI) end() {
127 - _, _ = a.Write([]byte("END\n\n"))
128 -}
src/go/otel-collector/exporter/netdataexporter/netdatachart.go deleted
-28
@@ -1,28 +0,0 @@
1 -package netdataexporter
2 -
3 -//type ChartDefinition struct {
4 -// ID string // must be globally unique
5 -// Title string
6 -// Units string
7 -// Family string
8 -// Context string // metric name
9 -// Type string // line, area, stacked
10 -// Options string // set to "obsolete" to delete the chart, otherwise empty string
11 -// Labels []LabelDefinition
12 -// Dimensions []DimensionDefinition
13 -// IsNew bool // Indicates if this chart is new and needs to be sent to Netdata
14 -//}
15 -//
16 -//// LabelDefinition represents a Netdata chart label
17 -//type LabelDefinition struct {
18 -// Name string
19 -// Value string
20 -//}
21 -//
22 -//// DimensionDefinition represents a Netdata chart dimension
23 -//type DimensionDefinition struct {
24 -// ID string // must be unique within the chart
25 -// Name string // replaces ID in UI
26 -// Algo string // absolute (Gauge), incremental (Counter)
27 -// Value float64
28 -//}
src/go/otel-collector/release-config.yaml.in deleted
-26
@@ -1,26 +0,0 @@
1 -dist:
2 - name: otelcol.plugin
3 - module: github.com/netdata/netdata/otel-collector
4 - description: OpenTelemetry Collector Distribution built for Netdata
5 - output_path: @CMAKE_BINARY_DIR@/otel-collector
6 - version: @NETDATA_VERSION_STRING@
7 - go: @GO_EXECUTABLE@
8 - debug_compilation: @DEBUG_BUILD@
9 -
10 -receivers:
11 - - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.137.0
12 - - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver v0.137.0
13 - - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver v0.137.0
14 - - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver v0.137.0
15 -
16 -exporters:
17 - - gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.137.0
18 - - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter v0.137.0
19 - - gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.137.0
20 - - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/prometheusexporter v0.137.0
21 - - gomod: github.com/netdata/netdata/otel-collector/exporter/journaldexporter v0.0.0
22 - - gomod: github.com/netdata/netdata/otel-collector/exporter/netdataexporter v0.0.0
23 -
24 -replaces:
25 - - github.com/netdata/netdata/otel-collector/exporter/journaldexporter => @CMAKE_CURRENT_SOURCE_DIR@/exporter/journaldexporter
26 - - github.com/netdata/netdata/otel-collector/exporter/netdataexporter => @CMAKE_CURRENT_SOURCE_DIR@/exporter/netdataexporter