feat(inputs.opentelemetry): Add profiles support (#15637)

This commit is contained in:
Sven Rebhan 2024-08-09 10:42:53 +02:00 committed by GitHub
parent ec1fc7fdc8
commit 8903637a84
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 1142 additions and 70 deletions

View File

@ -190,6 +190,7 @@ following works:
- github.com/grafana/regexp [BSD 3-Clause "New" or "Revised" License](https://github.com/grafana/regexp/blob/main/LICENSE)
- github.com/grid-x/modbus [BSD 3-Clause "New" or "Revised" License](https://github.com/grid-x/modbus/blob/master/LICENSE)
- github.com/grid-x/serial [MIT License](https://github.com/grid-x/serial/blob/master/LICENSE)
- github.com/grpc-ecosystem/grpc-gateway [BSD 3-Clause "New" or "Revised" License](https://github.com/grpc-ecosystem/grpc-gateway/blob/main/LICENSE)
- github.com/gsterjov/go-libsecret [MIT License](https://github.com/gsterjov/go-libsecret/blob/master/LICENSE)
- github.com/gwos/tcg/sdk [MIT License](https://github.com/gwos/tcg/blob/master/LICENSE)
- github.com/hailocab/go-hostpool [MIT License](https://github.com/hailocab/go-hostpool/blob/master/LICENSE)
@ -399,6 +400,7 @@ following works:
- go.opentelemetry.io/otel [Apache License 2.0](https://github.com/open-telemetry/opentelemetry-go/blob/main/LICENSE)
- go.opentelemetry.io/otel/metric [Apache License 2.0](https://github.com/open-telemetry/opentelemetry-go/blob/main/LICENSE)
- go.opentelemetry.io/otel/trace [Apache License 2.0](https://github.com/open-telemetry/opentelemetry-go/blob/main/LICENSE)
- go.opentelemetry.io/proto/otlp [Apache License 2.0](https://github.com/open-telemetry/opentelemetry-proto-go/blob/main/LICENSE)
- go.starlark.net [BSD 3-Clause "New" or "Revised" License](https://github.com/google/starlark-go/blob/master/LICENSE)
- go.step.sm/crypto [Apache License 2.0](https://github.com/smallstep/crypto/blob/master/LICENSE)
- go.uber.org/atomic [MIT License](https://pkg.go.dev/go.uber.org/atomic?tab=licenses)

4
go.mod
View File

@ -205,9 +205,10 @@ require (
github.com/xdg/scram v1.0.5
github.com/yuin/goldmark v1.6.0
go.mongodb.org/mongo-driver v1.16.0
go.opentelemetry.io/collector/pdata v1.8.0
go.opentelemetry.io/collector/pdata v1.12.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0
go.opentelemetry.io/otel/sdk/metric v1.27.0
go.opentelemetry.io/proto/otlp v1.3.1
go.starlark.net v0.0.0-20240520160348-046347dcd104
go.step.sm/crypto v0.50.0
golang.org/x/crypto v0.25.0
@ -492,7 +493,6 @@ require (
go.opentelemetry.io/otel/metric v1.27.0 // indirect
go.opentelemetry.io/otel/sdk v1.27.0 // indirect
go.opentelemetry.io/otel/trace v1.27.0 // indirect
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.24.0 // indirect

8
go.sum
View File

@ -2480,8 +2480,8 @@ go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/collector v0.81.0 h1:pF+sB8xNXlg/W0a0QTLz4mUWyool1a9toVj8LmLoFqg=
go.opentelemetry.io/collector/consumer v0.101.0 h1:9tDxaeHe1+Uovf3fhdx7T4pV5mo/Dc0hniH7O5H3RBA=
go.opentelemetry.io/collector/consumer v0.101.0/go.mod h1:ud5k64on9m7hHTrhjEeLhWbLkd8+Gp06rDt3p86TKNs=
go.opentelemetry.io/collector/pdata v1.8.0 h1:d/QQgZxB4Y+d3mqLVh2ozvzujUhloD3P/fk7X+In764=
go.opentelemetry.io/collector/pdata v1.8.0/go.mod h1:/W7clu0wFC4WSRp94Ucn6Vm36Wkrt+tmtlDb1aiNZCY=
go.opentelemetry.io/collector/pdata v1.12.0 h1:Xx5VK1p4VO0md8MWm2icwC1MnJ7f8EimKItMWw46BmA=
go.opentelemetry.io/collector/pdata v1.12.0/go.mod h1:MYeB0MmMAxeM0hstCFrCqWLzdyeYySim2dG6pDT6nYI=
go.opentelemetry.io/collector/pdata/testdata v0.101.0 h1:JzeUtg5RN1iIFgY8DakGlqBkGxOTJlkaYlLausnEGKY=
go.opentelemetry.io/collector/pdata/testdata v0.101.0/go.mod h1:ZGobfCus4fWo5RduZ7ENI0+HD9BewgKuO6qU2rBVnUg=
go.opentelemetry.io/collector/semconv v0.101.0 h1:tOe9iTe9dDCnvz/bqgfNRr4w80kXG8505tQJ5h5v08Q=
@ -2509,8 +2509,8 @@ go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39S
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94=
go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A=
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
go.starlark.net v0.0.0-20240520160348-046347dcd104 h1:3qhteRISupnJvaWshOmeqEUs2y9oc/+/ePPvDh3Eygg=
go.starlark.net v0.0.0-20240520160348-046347dcd104/go.mod h1:YKMCv9b1WrfWmeqdV5MAuEHWsu5iC+fe6kYl2sQjdI8=
go.step.sm/crypto v0.50.0 h1:BqI9sEgocoHDLLHiZnFqdqXl5FjdMvOWKMm/fKL/lrw=

View File

@ -42,10 +42,7 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
## These are always included as tags:
## - trace ID
## - span ID
## The default values are strongly recommended for use with Jaeger:
## - service.name
## - span.name
## Other common attributes can be found here:
## Common attributes can be found here:
## - https://github.com/open-telemetry/opentelemetry-collector/tree/main/semconv
# span_dimensions = ["service.name", "span.name"]
@ -53,14 +50,25 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
## These are always included as tags, if available:
## - trace ID
## - span ID
## The default values:
## - service.name
## Other common attributes can be found here:
## Common attributes can be found here:
## - https://github.com/open-telemetry/opentelemetry-collector/tree/main/semconv
## When using InfluxDB for both logs and traces, be certain that log_record_dimensions
## matches the span_dimensions value.
# log_record_dimensions = ["service.name"]
## Override the default profile attributes to be used as line protocol tags.
## These are always included as tags, if available:
## - profile_id
## - address
## - sample
## - sample_name
## - sample_unit
## - sample_type
## - sample_type_unit
## Common attributes can be found here:
## - https://github.com/open-telemetry/opentelemetry-collector/tree/main/semconv
# profile_dimensions = []
## Override the default (prometheus-v1) metrics schema.
## Supports: "prometheus-v1", "prometheus-v2"
## For more information about the alternatives, read the Prometheus input
@ -148,3 +156,19 @@ logs fluent.tag="fluent.info",pid=18i,ppid=9i,worker=0i 1613769568895331700
logs fluent.tag="fluent.debug",instance=1720i,queue_size=0i,stage_size=0i 1613769568895697200
logs fluent.tag="fluent.info",worker=0i 1613769568896515100
```
### Profiles
```text
profiles,address=95210353,host.name=testbox,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=0,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="fab9b8c848218405738c11a7ec4982e9",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=18694144u,filename="chromium",frame_type="native",location="",memory_limit=250413056u,memory_start=18698240u,stack_trace_id="hYmAzQVF8vy8MWbzsKpQNw",start_time_unix_nano=1721306050081621681u,value=1i 1721306048731622020
profiles,address=15945263,host.name=testbox,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=1,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="7dab4a2e0005d025e75cc72191f8d6bf",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=15638528u,filename="dockerd",frame_type="native",location="",memory_limit=47255552u,memory_start=15638528u,stack_trace_id="4N3KEcGylb5Qoi2905c1ZA",start_time_unix_nano=1721306050081621681u,value=1i 1721306049831718725
profiles,address=15952400,host.name=testbox,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=1,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="7dab4a2e0005d025e75cc72191f8d6bf",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=15638528u,filename="dockerd",frame_type="native",location="",memory_limit=47255552u,memory_start=15638528u,stack_trace_id="4N3KEcGylb5Qoi2905c1ZA",start_time_unix_nano=1721306050081621681u,value=1i 1721306049831718725
profiles,address=15953899,host.name=testbox,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=1,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="7dab4a2e0005d025e75cc72191f8d6bf",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=15638528u,filename="dockerd",frame_type="native",location="",memory_limit=47255552u,memory_start=15638528u,stack_trace_id="4N3KEcGylb5Qoi2905c1ZA",start_time_unix_nano=1721306050081621681u,value=1i 1721306049831718725
profiles,address=16148175,host.name=testbox,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=1,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="7dab4a2e0005d025e75cc72191f8d6bf",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=15638528u,filename="dockerd",frame_type="native",location="",memory_limit=47255552u,memory_start=15638528u,stack_trace_id="4N3KEcGylb5Qoi2905c1ZA",start_time_unix_nano=1721306050081621681u,value=1i 1721306049831718725
profiles,address=4770577,host.name=testbox,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=2,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="cfc3dc7d1638c1284a6b62d4b5c0d74e",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=0u,filename="",frame_type="kernel",location="do_epoll_wait",memory_limit=0u,memory_start=0u,stack_trace_id="UaO9bysJnAYXFYobSdHXqg",start_time_unix_nano=1721306050081621681u,value=1i 1721306050081621681
profiles,address=4773632,host.name=testbox,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=2,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="cfc3dc7d1638c1284a6b62d4b5c0d74e",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=0u,filename="",frame_type="kernel",location="__x64_sys_epoll_wait",memory_limit=0u,memory_start=0u,stack_trace_id="UaO9bysJnAYXFYobSdHXqg",start_time_unix_nano=1721306050081621681u,value=1i 1721306050081621681
profiles,address=14783666,host.name=testbox,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=2,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="cfc3dc7d1638c1284a6b62d4b5c0d74e",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=0u,filename="",frame_type="kernel",location="do_syscall_64",memory_limit=0u,memory_start=0u,stack_trace_id="UaO9bysJnAYXFYobSdHXqg",start_time_unix_nano=1721306050081621681u,value=1i 1721306050081621681
profiles,address=16777518,host.name=testbox,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=2,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="cfc3dc7d1638c1284a6b62d4b5c0d74e",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=0u,filename="",frame_type="kernel",location="entry_SYSCALL_64_after_hwframe",memory_limit=0u,memory_start=0u,stack_trace_id="UaO9bysJnAYXFYobSdHXqg",start_time_unix_nano=1721306050081621681u,value=1i 1721306050081621681
profiles,address=1139937,host.name=testbox,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=2,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="982ed6c7a77f99f0ae746be0187953bf",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=147456u,filename="libc.so.6",frame_type="native",location="",memory_limit=1638400u,memory_start=147456u,stack_trace_id="UaO9bysJnAYXFYobSdHXqg",start_time_unix_nano=1721306050081621681u,value=1i 1721306050081621681
profiles,address=117834912,host.name=testbox,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=2,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="fab9b8c848218405738c11a7ec4982e9",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=18694144u,filename="chromium",frame_type="native",location="",memory_limit=250413056u,memory_start=18698240u,stack_trace_id="UaO9bysJnAYXFYobSdHXqg",start_time_unix_nano=1721306050081621681u,value=1i 1721306050081621681
```

View File

@ -0,0 +1,134 @@
package opentelemetry
import (
"context"
"encoding/hex"
"fmt"
"strconv"
"strings"
"time"
service "go.opentelemetry.io/proto/otlp/collector/profiles/v1experimental"
"google.golang.org/protobuf/encoding/protojson"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/filter"
)
type profileService struct {
service.UnimplementedProfilesServiceServer
acc telegraf.Accumulator
filter filter.Filter
logger telegraf.Logger
}
func newProfileService(acc telegraf.Accumulator, logger telegraf.Logger, dimensions []string) (*profileService, error) {
// Check for duplicate dimensions
seen := make(map[string]bool, len(dimensions))
duplicates := make([]string, 0)
dims := make([]string, 0, len(dimensions))
for _, d := range dimensions {
if seen[d] {
duplicates = append(duplicates, d)
continue
}
dims = append(dims, d)
seen[d] = true
}
if len(duplicates) > 0 {
return nil, fmt.Errorf("duplicate profile dimension(s) configured: %s", strings.Join(duplicates, ","))
}
f, err := filter.Compile(dims)
if err != nil {
return nil, fmt.Errorf("compiling dimensions filter failed: %w", err)
}
return &profileService{
acc: acc,
filter: f,
logger: logger,
}, nil
}
func (s *profileService) Export(_ context.Context, req *service.ExportProfilesServiceRequest) (*service.ExportProfilesServiceResponse, error) {
// Output the received message for debugging
buf, err := protojson.Marshal(req)
if err != nil {
s.logger.Errorf("marshalling received profile failed: %v", err)
} else {
s.logger.Debugf("received profile: %s", string(buf))
}
for _, rp := range req.ResourceProfiles {
// Extract the requested attributes that should be added as tags
attrtags := make(map[string]string)
for _, attr := range rp.Resource.Attributes {
if s.filter.Match(attr.Key) {
attrtags[attr.Key] = attr.GetValue().GetStringValue()
}
}
for _, sp := range rp.ScopeProfiles {
for _, p := range sp.Profiles {
for i, sample := range p.Profile.Sample {
for j := sample.LocationsStartIndex; j < sample.LocationsStartIndex+sample.LocationsLength; j++ {
for validx, value := range sample.Value {
loc := p.Profile.Location[j]
locations := make([]string, 0, len(loc.Line))
for _, line := range loc.Line {
f := p.Profile.Function[line.FunctionIndex]
fileloc := p.Profile.StringTable[f.Filename]
if f.StartLine > 0 {
if fileloc != "" {
fileloc += " "
}
fileloc += "line " + strconv.FormatInt(f.StartLine, 10)
}
l := p.Profile.StringTable[f.Name]
if fileloc != "" {
l += "(" + fileloc + ")"
}
locations = append(locations, l)
}
mapping := p.Profile.Mapping[loc.MappingIndex]
tags := map[string]string{
"profile_id": hex.EncodeToString(p.ProfileId),
"sample": strconv.Itoa(i),
"sample_name": p.Profile.StringTable[p.Profile.PeriodType.Type],
"sample_unit": p.Profile.StringTable[p.Profile.PeriodType.Unit],
"sample_type": p.Profile.StringTable[p.Profile.SampleType[validx].Type],
"sample_type_unit": p.Profile.StringTable[p.Profile.SampleType[validx].Unit],
"address": "0x" + strconv.FormatUint(loc.Address, 16),
}
for k, v := range attrtags {
tags[k] = v
}
fields := map[string]interface{}{
"start_time_unix_nano": p.StartTimeUnixNano,
"end_time_unix_nano": p.EndTimeUnixNano,
"location": strings.Join(locations, ","),
"frame_type": p.Profile.StringTable[loc.TypeIndex],
"stack_trace_id": p.Profile.StringTable[sample.StacktraceIdIndex],
"memory_start": mapping.MemoryStart,
"memory_limit": mapping.MemoryLimit,
"filename": p.Profile.StringTable[mapping.Filename],
"file_offset": mapping.FileOffset,
"build_id": p.Profile.StringTable[mapping.BuildId],
"build_id_type": mapping.BuildIdKind.String(),
"value": value,
}
for _, idx := range sample.Attributes {
attr := p.Profile.AttributeTable[idx]
fields[attr.Key] = attr.GetValue().Value
}
ts := sample.TimestampsUnixNano[validx]
s.acc.AddFields("profiles", fields, tags, time.Unix(0, int64(ts)))
}
}
}
}
}
}
return &service.ExportProfilesServiceResponse{}, nil
}

View File

@ -8,13 +8,14 @@ import (
"sync"
"time"
"github.com/influxdata/influxdb-observability/otel2influx"
"go.opentelemetry.io/collector/pdata/plog/plogotlp"
"go.opentelemetry.io/collector/pdata/pmetric/pmetricotlp"
"go.opentelemetry.io/collector/pdata/ptrace/ptraceotlp"
pprofileotlp "go.opentelemetry.io/proto/otlp/collector/profiles/v1experimental"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"github.com/influxdata/influxdb-observability/otel2influx"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/config"
"github.com/influxdata/telegraf/plugins/common/tls"
@ -28,11 +29,11 @@ type OpenTelemetry struct {
ServiceAddress string `toml:"service_address"`
SpanDimensions []string `toml:"span_dimensions"`
LogRecordDimensions []string `toml:"log_record_dimensions"`
ProfileDimensions []string `toml:"profile_dimensions"`
MetricsSchema string `toml:"metrics_schema"`
MaxMsgSize config.Size `toml:"max_msg_size"`
Timeout config.Duration `toml:"timeout"`
Log telegraf.Logger `toml:"-"`
tls.ServerConfig
listener net.Listener // overridden in tests
@ -45,11 +46,26 @@ func (*OpenTelemetry) SampleConfig() string {
return sampleConfig
}
func (o *OpenTelemetry) Gather(_ telegraf.Accumulator) error {
func (*OpenTelemetry) Gather(telegraf.Accumulator) error {
return nil
}
func (o *OpenTelemetry) Start(accumulator telegraf.Accumulator) error {
func (o *OpenTelemetry) Init() error {
if o.ServiceAddress == "" {
o.ServiceAddress = "0.0.0.0:4317"
}
switch o.MetricsSchema {
case "": // Set default
o.MetricsSchema = "prometheus-v1"
case "prometheus-v1", "prometheus-v2": // Valid values
default:
return fmt.Errorf("invalid metric schema %q", o.MetricsSchema)
}
return nil
}
func (o *OpenTelemetry) Start(acc telegraf.Accumulator) error {
var grpcOptions []grpc.ServerOption
if tlsConfig, err := o.ServerConfig.TLSConfig(); err != nil {
return err
@ -64,7 +80,7 @@ func (o *OpenTelemetry) Start(accumulator telegraf.Accumulator) error {
}
logger := &otelLogger{o.Log}
influxWriter := &writeToAccumulator{accumulator}
influxWriter := &writeToAccumulator{acc}
o.grpcServer = grpc.NewServer(grpcOptions...)
traceSvc, err := newTraceService(logger, influxWriter, o.SpanDimensions)
@ -72,30 +88,36 @@ func (o *OpenTelemetry) Start(accumulator telegraf.Accumulator) error {
return err
}
ptraceotlp.RegisterGRPCServer(o.grpcServer, traceSvc)
metricsSvc, err := newMetricsService(logger, influxWriter, o.MetricsSchema)
if err != nil {
return err
}
pmetricotlp.RegisterGRPCServer(o.grpcServer, metricsSvc)
logsSvc, err := newLogsService(logger, influxWriter, o.LogRecordDimensions)
if err != nil {
return err
}
plogotlp.RegisterGRPCServer(o.grpcServer, logsSvc)
if o.listener == nil {
o.listener, err = net.Listen("tcp", o.ServiceAddress)
if err != nil {
return err
}
profileSvc, err := newProfileService(acc, o.Log, o.ProfileDimensions)
if err != nil {
return err
}
pprofileotlp.RegisterProfilesServiceServer(o.grpcServer, profileSvc)
o.listener, err = net.Listen("tcp", o.ServiceAddress)
if err != nil {
return err
}
o.wg.Add(1)
go func() {
defer o.wg.Done()
if err := o.grpcServer.Serve(o.listener); err != nil {
accumulator.AddError(fmt.Errorf("failed to stop OpenTelemetry gRPC service: %w", err))
acc.AddError(fmt.Errorf("failed to stop OpenTelemetry gRPC service: %w", err))
}
o.wg.Done()
}()
return nil
@ -105,6 +127,7 @@ func (o *OpenTelemetry) Stop() {
if o.grpcServer != nil {
o.grpcServer.Stop()
}
o.listener = nil
o.wg.Wait()
}
@ -112,10 +135,8 @@ func (o *OpenTelemetry) Stop() {
func init() {
inputs.Add("opentelemetry", func() telegraf.Input {
return &OpenTelemetry{
ServiceAddress: "0.0.0.0:4317",
SpanDimensions: otel2influx.DefaultOtelTracesToLineProtocolConfig().SpanDimensions,
LogRecordDimensions: otel2influx.DefaultOtelLogsToLineProtocolConfig().LogRecordDimensions,
MetricsSchema: "prometheus-v1",
Timeout: config.Duration(5 * time.Second),
}
})

View File

@ -3,78 +3,250 @@ package opentelemetry
import (
"context"
"net"
"os"
"path/filepath"
"runtime"
"sort"
"strings"
"testing"
"time"
"go.opentelemetry.io/otel/sdk/metric/metricdata"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/metricdata"
otlplogs "go.opentelemetry.io/proto/otlp/collector/logs/v1"
otlpmetrics "go.opentelemetry.io/proto/otlp/collector/metrics/v1"
otlpprofiles "go.opentelemetry.io/proto/otlp/collector/profiles/v1experimental"
otlptrace "go.opentelemetry.io/proto/otlp/collector/trace/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/test/bufconn"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/protobuf/encoding/protojson"
"github.com/influxdata/influxdb-observability/otel2influx"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/config"
tmetric "github.com/influxdata/telegraf/metric"
"github.com/influxdata/telegraf/plugins/inputs"
"github.com/influxdata/telegraf/plugins/parsers/influx"
"github.com/influxdata/telegraf/testutil"
)
func TestOpenTelemetry(t *testing.T) {
// create mock OpenTelemetry client
// Setup and start the plugin
plugin := &OpenTelemetry{
MetricsSchema: "prometheus-v1",
}
require.NoError(t, plugin.Init())
mockListener := bufconn.Listen(1024 * 1024)
t.Cleanup(func() { _ = mockListener.Close() })
plugin := inputs.Inputs["opentelemetry"]().(*OpenTelemetry)
plugin.listener = mockListener
accumulator := new(testutil.Accumulator)
require.NoError(t, plugin.Start(accumulator))
t.Cleanup(plugin.Stop)
var acc testutil.Accumulator
require.NoError(t, plugin.Start(&acc))
defer plugin.Stop()
// Setup the OpenTelemetry exporter
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
t.Cleanup(cancel)
defer cancel()
metricExporter, err := otlpmetricgrpc.New(ctx,
exporter, err := otlpmetricgrpc.New(ctx,
otlpmetricgrpc.WithInsecure(),
otlpmetricgrpc.WithDialOption(
grpc.WithBlock(), //nolint:staticcheck // grpc.WithBlock is deprecated, but no alternative is provided
grpc.WithContextDialer(func(ctx context.Context, _ string) (net.Conn, error) {
return mockListener.DialContext(ctx)
grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) {
return net.Dial("tcp", plugin.listener.Addr().String())
})),
)
require.NoError(t, err)
//nolint:errcheck // test cleanup
t.Cleanup(func() { metricExporter.Shutdown(ctx) })
defer exporter.Shutdown(ctx) //nolint:errcheck // We cannot do anything if the shutdown fails
// Setup the metric to send
reader := metric.NewManualReader()
mp := metric.NewMeterProvider(metric.WithReader(reader))
defer reader.Shutdown(ctx) //nolint:errcheck // We cannot do anything if the shutdown fails
// set a metric value
meter := mp.Meter("library-name")
provider := metric.NewMeterProvider(metric.WithReader(reader))
meter := provider.Meter("library-name")
counter, err := meter.Int64Counter("measurement-counter")
require.NoError(t, err)
counter.Add(ctx, 7)
// write metrics through the telegraf OpenTelemetry input plugin
// Write the OpenTelemetry metrics
var rm metricdata.ResourceMetrics
err = reader.Collect(ctx, &rm)
require.NoError(t, err)
require.NoError(t, metricExporter.Export(ctx, &rm))
require.NoError(t, reader.Collect(ctx, &rm))
require.NoError(t, exporter.Export(ctx, &rm))
// Shutdown
require.NoError(t, reader.Shutdown(ctx))
require.NoError(t, metricExporter.Shutdown(ctx))
require.NoError(t, exporter.Shutdown(ctx))
plugin.Stop()
// Check
require.Empty(t, acc.Errors)
require.Empty(t, accumulator.Errors)
require.Len(t, accumulator.Metrics, 1)
got := accumulator.Metrics[0]
require.Equal(t, "measurement-counter", got.Measurement)
require.Equal(t, telegraf.Counter, got.Type)
require.Equal(t, "library-name", got.Tags["otel.library.name"])
var exesuffix string
if runtime.GOOS == "windows" {
exesuffix = ".exe"
}
expected := []telegraf.Metric{
tmetric.New(
"measurement-counter",
map[string]string{
"otel.library.name": "library-name",
"service.name": "unknown_service:opentelemetry.test" + exesuffix,
"telemetry.sdk.language": "go",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.27.0",
},
map[string]interface{}{
"counter": 7,
},
time.Unix(0, 0),
telegraf.Counter,
),
}
actual := acc.GetTelegrafMetrics()
testutil.RequireMetricsEqual(t, expected, actual, testutil.IgnoreTime(), testutil.IgnoreFields("start_time_unix_nano"))
}
func TestCases(t *testing.T) {
// Get all directories in testdata
folders, err := os.ReadDir("testcases")
require.NoError(t, err)
// Register the plugin
inputs.Add("opentelemetry", func() telegraf.Input {
return &OpenTelemetry{
ServiceAddress: "127.0.0.1:0",
SpanDimensions: otel2influx.DefaultOtelTracesToLineProtocolConfig().SpanDimensions,
LogRecordDimensions: otel2influx.DefaultOtelLogsToLineProtocolConfig().LogRecordDimensions,
ProfileDimensions: []string{"host.name"},
Timeout: config.Duration(5 * time.Second),
}
})
// Prepare the influx parser for expectations
parser := &influx.Parser{}
require.NoError(t, parser.Init())
for _, f := range folders {
// Only handle folders
if !f.IsDir() {
continue
}
testcasePath := filepath.Join("testcases", f.Name())
configFilename := filepath.Join(testcasePath, "telegraf.conf")
inputFiles := filepath.Join(testcasePath, "*.json")
expectedFilename := filepath.Join(testcasePath, "expected.out")
expectedErrorFilename := filepath.Join(testcasePath, "expected.err")
// Compare options
options := []cmp.Option{
testutil.IgnoreTime(),
testutil.SortMetrics(),
testutil.IgnoreFields("start_time_unix_nano"),
}
t.Run(f.Name(), func(t *testing.T) {
// Read the input data
inputs := make(map[string][][]byte)
matches, err := filepath.Glob(inputFiles)
require.NoError(t, err)
require.NotEmpty(t, matches)
sort.Strings(matches)
for _, fn := range matches {
buf, err := os.ReadFile(fn)
require.NoError(t, err)
key := strings.TrimSuffix(filepath.Base(fn), ".json")
key, _, _ = strings.Cut(key, "_")
inputs[key] = append(inputs[key], buf)
}
// Read the expected output if any
var expected []telegraf.Metric
if _, err := os.Stat(expectedFilename); err == nil {
var err error
expected, err = testutil.ParseMetricsFromFile(expectedFilename, parser)
require.NoError(t, err)
}
// Read the expected output if any
var expectedErrors []string
if _, err := os.Stat(expectedErrorFilename); err == nil {
var err error
expectedErrors, err = testutil.ParseLinesFromFile(expectedErrorFilename)
require.NoError(t, err)
require.NotEmpty(t, expectedErrors)
}
// Configure the plugin
cfg := config.NewConfig()
require.NoError(t, cfg.LoadConfig(configFilename))
require.Len(t, cfg.Inputs, 1)
// Setup and start the plugin
plugin := cfg.Inputs[0].Input.(*OpenTelemetry)
require.NoError(t, plugin.Init())
var acc testutil.Accumulator
require.NoError(t, plugin.Start(&acc))
defer plugin.Stop()
// Send all data to the plugin
addr := plugin.listener.Addr().String()
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
grpcClient, err := grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
require.NoError(t, err)
defer grpcClient.Close()
for msgtype, messages := range inputs {
switch msgtype {
case "logs":
client := otlplogs.NewLogsServiceClient(grpcClient)
for _, buf := range messages {
var msg otlplogs.ExportLogsServiceRequest
require.NoError(t, protojson.Unmarshal(buf, &msg))
_, err := client.Export(ctx, &msg)
require.NoError(t, err)
}
case "metrics":
client := otlpmetrics.NewMetricsServiceClient(grpcClient)
for _, buf := range messages {
var msg otlpmetrics.ExportMetricsServiceRequest
require.NoError(t, protojson.Unmarshal(buf, &msg))
_, err := client.Export(ctx, &msg)
require.NoError(t, err)
}
case "profiles":
client := otlpprofiles.NewProfilesServiceClient(grpcClient)
for _, buf := range messages {
var msg otlpprofiles.ExportProfilesServiceRequest
require.NoError(t, protojson.Unmarshal(buf, &msg))
_, err := client.Export(ctx, &msg)
require.NoError(t, err)
}
case "traces":
client := otlptrace.NewTraceServiceClient(grpcClient)
for _, buf := range messages {
var msg otlptrace.ExportTraceServiceRequest
require.NoError(t, protojson.Unmarshal(buf, &msg))
_, err := client.Export(ctx, &msg)
require.NoError(t, err)
}
}
}
// Close the plugin to make sure all data is flushed
require.NoError(t, grpcClient.Close())
plugin.Stop()
// Check the metrics
require.Eventually(t, func() bool {
return acc.NMetrics() >= uint64(len(expected))
}, 3*time.Second, 100*time.Millisecond)
require.Empty(t, acc.Errors)
actual := acc.GetTelegrafMetrics()
testutil.RequireMetricsEqual(t, expected, actual, options...)
})
}
}

View File

@ -14,10 +14,7 @@
## These are always included as tags:
## - trace ID
## - span ID
## The default values are strongly recommended for use with Jaeger:
## - service.name
## - span.name
## Other common attributes can be found here:
## Common attributes can be found here:
## - https://github.com/open-telemetry/opentelemetry-collector/tree/main/semconv
# span_dimensions = ["service.name", "span.name"]
@ -25,14 +22,25 @@
## These are always included as tags, if available:
## - trace ID
## - span ID
## The default values:
## - service.name
## Other common attributes can be found here:
## Common attributes can be found here:
## - https://github.com/open-telemetry/opentelemetry-collector/tree/main/semconv
## When using InfluxDB for both logs and traces, be certain that log_record_dimensions
## matches the span_dimensions value.
# log_record_dimensions = ["service.name"]
## Override the default profile attributes to be used as line protocol tags.
## These are always included as tags, if available:
## - profile_id
## - address
## - sample
## - sample_name
## - sample_unit
## - sample_type
## - sample_type_unit
## Common attributes can be found here:
## - https://github.com/open-telemetry/opentelemetry-collector/tree/main/semconv
# profile_dimensions = []
## Override the default (prometheus-v1) metrics schema.
## Supports: "prometheus-v1", "prometheus-v2"
## For more information about the alternatives, read the Prometheus input

View File

@ -0,0 +1,11 @@
profiles,address=0x5accb71,host.name=Hugin,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=0,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="fab9b8c848218405738c11a7ec4982e9",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=18694144u,filename="chromium",frame_type="native",location="",memory_limit=250413056u,memory_start=18698240u,stack_trace_id="hYmAzQVF8vy8MWbzsKpQNw",start_time_unix_nano=1721306050081621681u,value=1i 1721306048731622020
profiles,address=0xf34e2f,host.name=Hugin,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=1,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="7dab4a2e0005d025e75cc72191f8d6bf",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=15638528u,filename="dockerd",frame_type="native",location="",memory_limit=47255552u,memory_start=15638528u,stack_trace_id="4N3KEcGylb5Qoi2905c1ZA",start_time_unix_nano=1721306050081621681u,value=1i 1721306049831718725
profiles,address=0xf36a10,host.name=Hugin,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=1,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="7dab4a2e0005d025e75cc72191f8d6bf",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=15638528u,filename="dockerd",frame_type="native",location="",memory_limit=47255552u,memory_start=15638528u,stack_trace_id="4N3KEcGylb5Qoi2905c1ZA",start_time_unix_nano=1721306050081621681u,value=1i 1721306049831718725
profiles,address=0xf36feb,host.name=Hugin,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=1,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="7dab4a2e0005d025e75cc72191f8d6bf",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=15638528u,filename="dockerd",frame_type="native",location="",memory_limit=47255552u,memory_start=15638528u,stack_trace_id="4N3KEcGylb5Qoi2905c1ZA",start_time_unix_nano=1721306050081621681u,value=1i 1721306049831718725
profiles,address=0xf666cf,host.name=Hugin,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=1,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="7dab4a2e0005d025e75cc72191f8d6bf",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=15638528u,filename="dockerd",frame_type="native",location="",memory_limit=47255552u,memory_start=15638528u,stack_trace_id="4N3KEcGylb5Qoi2905c1ZA",start_time_unix_nano=1721306050081621681u,value=1i 1721306049831718725
profiles,address=0x48cb11,host.name=Hugin,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=2,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="cfc3dc7d1638c1284a6b62d4b5c0d74e",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=0u,filename="",frame_type="kernel",location="do_epoll_wait",memory_limit=0u,memory_start=0u,stack_trace_id="UaO9bysJnAYXFYobSdHXqg",start_time_unix_nano=1721306050081621681u,value=1i 1721306050081621681
profiles,address=0x48d700,host.name=Hugin,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=2,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="cfc3dc7d1638c1284a6b62d4b5c0d74e",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=0u,filename="",frame_type="kernel",location="__x64_sys_epoll_wait",memory_limit=0u,memory_start=0u,stack_trace_id="UaO9bysJnAYXFYobSdHXqg",start_time_unix_nano=1721306050081621681u,value=1i 1721306050081621681
profiles,address=0xe194b2,host.name=Hugin,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=2,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="cfc3dc7d1638c1284a6b62d4b5c0d74e",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=0u,filename="",frame_type="kernel",location="do_syscall_64",memory_limit=0u,memory_start=0u,stack_trace_id="UaO9bysJnAYXFYobSdHXqg",start_time_unix_nano=1721306050081621681u,value=1i 1721306050081621681
profiles,address=0x100012e,host.name=Hugin,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=2,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="cfc3dc7d1638c1284a6b62d4b5c0d74e",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=0u,filename="",frame_type="kernel",location="entry_SYSCALL_64_after_hwframe",memory_limit=0u,memory_start=0u,stack_trace_id="UaO9bysJnAYXFYobSdHXqg",start_time_unix_nano=1721306050081621681u,value=1i 1721306050081621681
profiles,address=0x1164e1,host.name=Hugin,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=2,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="982ed6c7a77f99f0ae746be0187953bf",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=147456u,filename="libc.so.6",frame_type="native",location="",memory_limit=1638400u,memory_start=147456u,stack_trace_id="UaO9bysJnAYXFYobSdHXqg",start_time_unix_nano=1721306050081621681u,value=1i 1721306050081621681
profiles,address=0x70604a0,host.name=Hugin,profile_id=618098d29a6cefd6a4c0ea806880c2a8,sample=2,sample_name=cpu,sample_type=samples,sample_type_unit=count,sample_unit=nanoseconds build_id="fab9b8c848218405738c11a7ec4982e9",build_id_type="BUILD_ID_BINARY_HASH",end_time_unix_nano=1721306050081621681u,file_offset=18694144u,filename="chromium",frame_type="native",location="",memory_limit=250413056u,memory_start=18698240u,stack_trace_id="UaO9bysJnAYXFYobSdHXqg",start_time_unix_nano=1721306050081621681u,value=1i 1721306050081621681

View File

@ -0,0 +1,699 @@
{
"resourceProfiles": [
{
"resource": {
"attributes": [
{
"key": "profiling.agent.start_time",
"value": {
"stringValue": "1721306026320"
}
},
{
"key": "profiling.agent.env_https_proxy",
"value": {
"stringValue": ""
}
},
{
"key": "profiling.agent.config.tracers",
"value": {
"stringValue": "all"
}
},
{
"key": "profiling.agent.config.ca_address",
"value": {
"stringValue": "127.0.0.1:11000"
}
},
{
"key": "host:cpu/cache/L2-kbytes",
"value": {
"stringValue": "512"
}
},
{
"key": "profiling.host.kernel_version",
"value": {
"stringValue": "6.9.9-arch1-1"
}
},
{
"key": "profiling.agent.config.verbose",
"value": {
"stringValue": "false"
}
},
{
"key": "host:cpu/vendor/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/cores-per-socket",
"value": {
"stringValue": "8"
}
},
{
"key": "profiling.host.sysctl.kernel.unprivileged_bpf_disabled",
"value": {
"stringValue": "2"
}
},
{
"key": "profiling.agent.revision",
"value": {
"stringValue": "main-172652de"
}
},
{
"key": "host:cpu/clock/scaling-governor",
"value": {
"stringValue": "schedutil"
}
},
{
"key": "host:cpu/cache/L3-kbytes",
"value": {
"stringValue": "16384"
}
},
{
"key": "host:cpu/clock/min-mhz",
"value": {
"stringValue": "2200"
}
},
{
"key": "host:cpu/clock/scaling-cur-freq-mhz",
"value": {
"stringValue": "2226"
}
},
{
"key": "host:cpu/cpus",
"value": {
"stringValue": "16"
}
},
{
"key": "host:cpu/clock/min-mhz/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/cache/L2-kbytes/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "profiling.host.machine",
"value": {
"stringValue": "x86_64"
}
},
{
"key": "profiling.agent.version",
"value": {
"stringValue": "v0.0.0"
}
},
{
"key": "host:cpu/clock/max-mhz/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/flags",
"value": {
"stringValue": "3dnowprefetch,abm,adx,aes,aperfmperf,apic,arat,avic,avx,avx2,bmi1,bmi2,bpext,cat_l3,cdp_l3,clflush,clflushopt,clwb,clzero,cmov,cmp_legacy,constant_tsc,cpb,cpuid,cqm,cqm_llc,cqm_mbm_local,cqm_mbm_total,cqm_occup_llc,cr8_legacy,cx16,cx8,de,decodeassists,extapic,extd_apicid,f16c,flushbyasid,fma,fpu,fsgsbase,fxsr,fxsr_opt,ht,hw_pstate,ibpb,ibs,irperf,lahf_lm,lbrv,lm,mba,mca,mce,misalignsse,mmx,mmxext,monitor,movbe,msr,mtrr,mwaitx,nonstop_tsc,nopl,npt,nrip_save,nx,osvw,overflow_recov,pae,pat,pausefilter,pclmulqdq,pdpe1gb,perfctr_core,perfctr_llc,perfctr_nb,pfthreshold,pge,pni,popcnt,pse,pse36,rapl,rdpid,rdpru,rdrand,rdseed,rdt_a,rdtscp,rep_good,sep,sev,sev_es,sha_ni,skinit,smap,smca,smep,ssbd,sse,sse2,sse4_1,sse4_2,sse4a,ssse3,stibp,succor,svm,svm_lock,syscall,tce,topoext,tsc,tsc_scale,umip,v_spec_ctrl,v_vmsave_vmload,vgif,vmcb_clean,vme,vmmcall,wbnoinvd,wdt,x2apic,xgetbv1,xsave,xsavec,xsaveerptr,xsaveopt,xtopology"
}
},
{
"key": "profiling.agent.config.max_elements_per_interval",
"value": {
"stringValue": "1600"
}
},
{
"key": "host:cpu/model/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/clock/scaling-governor/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "profiling.agent.config.known_traces_entries",
"value": {
"stringValue": "65536"
}
},
{
"key": "profiling.agent.config.probabilistic_threshold",
"value": {
"stringValue": "100"
}
},
{
"key": "host:cpu/cache/L1i-kbytes/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/stepping",
"value": {
"stringValue": "0"
}
},
{
"key": "profiling.agent.config.probabilistic_interval",
"value": {
"stringValue": "1m0s"
}
},
{
"key": "profiling.agent.config.map_scale_factor",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/cpus/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/bugs/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/clock/scaling-driver/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/cache/L3-kbytes/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/cores-per-socket/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/clock/scaling-cur-freq-mhz/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "profiling.host.name",
"value": {
"stringValue": "Hugin"
}
},
{
"key": "host:cpu/clock/max-mhz",
"value": {
"stringValue": "4426"
}
},
{
"key": "profiling.host.sysctl.net.core.bpf_jit_enable",
"value": {
"stringValue": "1"
}
},
{
"key": "profiling.agent.config.bpf_log_size",
"value": {
"stringValue": "65536"
}
},
{
"key": "profiling.agent.config.present_cpu_cores",
"value": {
"stringValue": "16"
}
},
{
"key": "profiling.agent.build_timestamp",
"value": {
"stringValue": "1721228980"
}
},
{
"key": "profiling.host.kernel_proc_version",
"value": {
"stringValue": "Linux version 6.9.9-arch1-1 (linux@archlinux) (gcc (GCC) 14.1.1 20240522, GNU ld (GNU Binutils) 2.42.0) #1 SMP PREEMPT_DYNAMIC Fri, 12 Jul 2024 00:06:53 +0000\n"
}
},
{
"key": "host:cpu/threads-per-core/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/cache/L1d-kbytes/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "profiling.agent.config.file",
"value": {
"stringValue": "/etc/otel/profiling-agent/agent.conf"
}
},
{
"key": "profiling.agent.config.disable_tls",
"value": {
"stringValue": "true"
}
},
{
"key": "profiling.host.sysctl.kernel.bpf_stats_enabled",
"value": {
"stringValue": "0"
}
},
{
"key": "profiling.agent.config.tags",
"value": {
"stringValue": ""
}
},
{
"key": "host:cpu/clock/scaling-driver",
"value": {
"stringValue": "acpi-cpufreq"
}
},
{
"key": "host:cpu/online/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/cache/L1d-kbytes",
"value": {
"stringValue": "32"
}
},
{
"key": "profiling.agent.config.bpf_log_level",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/model-name/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host.arch",
"value": {
"stringValue": "amd64"
}
},
{
"key": "host:cpu/bugs",
"value": {
"stringValue": "retbleed,smt_rsb,spec_store_bypass,spectre_v1,spectre_v2,srso,sysret_ss_attrs"
}
},
{
"key": "host:cpu/threads-per-core",
"value": {
"stringValue": "2"
}
},
{
"key": "host:cpu/online",
"value": {
"stringValue": "0-15"
}
},
{
"key": "host:cpu/stepping/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/model-name",
"value": {
"stringValue": "AMD Ryzen 7 3700X 8-Core Processor"
}
},
{
"key": "profiling.host.ip",
"value": {
"stringValue": "127.0.0.1"
}
},
{
"key": "profiling.agent.config.cache_directory",
"value": {
"stringValue": "/var/cache/otel/profiling-agent"
}
},
{
"key": "profiling.agent.config.no_kernel_version_check",
"value": {
"stringValue": "false"
}
},
{
"key": "host:cpu/model",
"value": {
"stringValue": "113"
}
},
{
"key": "host:cpu/vendor",
"value": {
"stringValue": "AuthenticAMD"
}
},
{
"key": "host:cpu/flags/socketIDs",
"value": {
"stringValue": "0"
}
},
{
"key": "host:cpu/cache/L1i-kbytes",
"value": {
"stringValue": "32"
}
},
{
"key": "profiling.project.id",
"value": {
"stringValue": "1"
}
},
{
"key": "host.id",
"value": {
"stringValue": "1693958027216639598"
}
},
{
"key": "host.ip",
"value": {
"stringValue": "127.0.0.1"
}
},
{
"key": "host.name",
"value": {
"stringValue": "Hugin"
}
},
{
"key": "service.version",
"value": {
"stringValue": ""
}
},
{
"key": "os.kernel",
"value": {
"stringValue": "6.9.9-arch1-1"
}
}
]
},
"scopeProfiles": [
{
"scope": {},
"profiles": [
{
"profileId": "YYCY0pps79akwOqAaIDCqA==",
"startTimeUnixNano": "1721306050081621681",
"endTimeUnixNano": "1721306050081621681",
"profile": {
"sampleType": [
{
"type": "1",
"unit": "2"
}
],
"sample": [
{
"locationsLength": "1",
"stacktraceIdIndex": 5,
"value": [
"1"
],
"attributes": [
"0"
],
"timestampsUnixNano": [
"1721306048731622020"
]
},
{
"locationsStartIndex": "1",
"locationsLength": "4",
"stacktraceIdIndex": 9,
"value": [
"1"
],
"attributes": [
"1"
],
"timestampsUnixNano": [
"1721306049831718725"
]
},
{
"locationsStartIndex": "5",
"locationsLength": "6",
"stacktraceIdIndex": 12,
"value": [
"1"
],
"attributes": [
"2"
],
"timestampsUnixNano": [
"1721306050081621681"
]
}
],
"mapping": [
{
"memoryStart": "18698240",
"memoryLimit": "250413056",
"fileOffset": "18694144",
"filename": "7",
"buildId": "8",
"buildIdKind": "BUILD_ID_BINARY_HASH"
},
{
"memoryStart": "15638528",
"memoryLimit": "47255552",
"fileOffset": "15638528",
"filename": "10",
"buildId": "11",
"buildIdKind": "BUILD_ID_BINARY_HASH"
},
{
"buildId": "14",
"buildIdKind": "BUILD_ID_BINARY_HASH"
},
{
"memoryStart": "147456",
"memoryLimit": "1638400",
"fileOffset": "147456",
"filename": "15",
"buildId": "16",
"buildIdKind": "BUILD_ID_BINARY_HASH"
}
],
"location": [
{
"address": "95210353",
"typeIndex": 6
},
{
"mappingIndex": "1",
"address": "15945263",
"typeIndex": 6
},
{
"mappingIndex": "1",
"address": "15952400",
"typeIndex": 6
},
{
"mappingIndex": "1",
"address": "15953899",
"typeIndex": 6
},
{
"mappingIndex": "1",
"address": "16148175",
"typeIndex": 6
},
{
"mappingIndex": "2",
"address": "4770577",
"line": [
{
"functionIndex": "1"
}
],
"typeIndex": 13
},
{
"mappingIndex": "2",
"address": "4773632",
"line": [
{
"functionIndex": "2"
}
],
"typeIndex": 13
},
{
"mappingIndex": "2",
"address": "14783666",
"line": [
{
"functionIndex": "3"
}
],
"typeIndex": 13
},
{
"mappingIndex": "2",
"address": "16777518",
"line": [
{
"functionIndex": "4"
}
],
"typeIndex": 13
},
{
"mappingIndex": "3",
"address": "1139937",
"typeIndex": 6
},
{
"address": "117834912",
"typeIndex": 6
}
],
"locationIndices": [
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10"
],
"function": [
{},
{
"name": "20"
},
{
"name": "17"
},
{
"name": "18"
},
{
"name": "19"
}
],
"attributeTable": [
{
"key": "thread.name",
"value": {
"stringValue": "chromium"
}
},
{
"key": "thread.name",
"value": {
"stringValue": "dockerd"
}
},
{
"key": "thread.name",
"value": {
"stringValue": "ThreadPoolServi"
}
}
],
"stringTable": [
"",
"samples",
"count",
"cpu",
"nanoseconds",
"hYmAzQVF8vy8MWbzsKpQNw",
"native",
"chromium",
"fab9b8c848218405738c11a7ec4982e9",
"4N3KEcGylb5Qoi2905c1ZA",
"dockerd",
"7dab4a2e0005d025e75cc72191f8d6bf",
"UaO9bysJnAYXFYobSdHXqg",
"kernel",
"cfc3dc7d1638c1284a6b62d4b5c0d74e",
"libc.so.6",
"982ed6c7a77f99f0ae746be0187953bf",
"__x64_sys_epoll_wait",
"do_syscall_64",
"entry_SYSCALL_64_after_hwframe",
"do_epoll_wait"
],
"timeNanos": "1721306050081621681",
"periodType": {
"type": "3",
"unit": "4"
},
"period": "50000000"
}
}
]
}
]
}
]
}

View File

@ -0,0 +1 @@
[[inputs.opentelemetry]]