open-telemetry / opentelemetry-collector-contrib

Contrib repository for the OpenTelemetry Collector
https://opentelemetry.io
Apache License 2.0
2.7k stars 2.14k forks source link

ParseJSON doesn't allow leading square bracket #33535

Open Marty1703 opened 1 week ago

Marty1703 commented 1 week ago

Component(s)

pkg/ottl

What happened?

Description

My (valid) JSON starting with a squared bracket isn't processed correctly by the ParseJSON function

Steps to Reproduce

Add transform

       transform:
        log_statements:
        - context: log
          statements:
          - set(attributes["MyBody"], ParseJSON(attributes["Body"])) where IsMatch(attributes["Body"], "^\\[")

Process JSON [ {"id":"123","description": "test description"}, {"id":"456","description": "test description"} ]

Expected Result

Correction parsing of JSON array objects.

Actual Result

2024-06-13T06:13:00.722Z error logs/processor.go:54 failed processing logs {"kind": "processor", "name": "transform", "pipeline": "logs", "error": "failed to execute statement: set(attributes[\"MyBody\"], ParseJSON(attributes[\"Body\"])) where IsMatch(attributes[\"Body\"], \"^\\\\[\"), ReadMapCB: expect { or n, but found [, error found in #1 byte of ...|[{\"id\":\"123|..., bigger context ...|[{\"id\":\"123\",\"description\":\"test description\"},|..."} github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor/internal/logs.(*Processor).ProcessLogs github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor@v0.101.0/internal/logs/processor.go:54 go.opentelemetry.io/collector/processor/processorhelper.NewLogsProcessor.func1 go.opentelemetry.io/collector/processor@v0.101.0/processorhelper/logs.go:48 go.opentelemetry.io/collector/consumer.ConsumeLogsFunc.ConsumeLogs go.opentelemetry.io/collector/consumer@v0.101.0/logs.go:25 go.opentelemetry.io/collector/processor/processorhelper.NewLogsProcessor.func1 go.opentelemetry.io/collector/processor@v0.101.0/processorhelper/logs.go:56 go.opentelemetry.io/collector/consumer.ConsumeLogsFunc.ConsumeLogs go.opentelemetry.io/collector/consumer@v0.101.0/logs.go:25 go.opentelemetry.io/collector/processor/processorhelper.NewLogsProcessor.func1 go.opentelemetry.io/collector/processor@v0.101.0/processorhelper/logs.go:56 go.opentelemetry.io/collector/consumer.ConsumeLogsFunc.ConsumeLogs go.opentelemetry.io/collector/consumer@v0.101.0/logs.go:25 go.opentelemetry.io/collector/processor/processorhelper.NewLogsProcessor.func1 go.opentelemetry.io/collector/processor@v0.101.0/processorhelper/logs.go:56 go.opentelemetry.io/collector/consumer.ConsumeLogsFunc.ConsumeLogs go.opentelemetry.io/collector/consumer@v0.101.0/logs.go:25 go.opentelemetry.io/collector/processor/processorhelper.NewLogsProcessor.func1 go.opentelemetry.io/collector/processor@v0.101.0/processorhelper/logs.go:56 go.opentelemetry.io/collector/consumer.ConsumeLogsFunc.ConsumeLogs go.opentelemetry.io/collector/consumer@v0.101.0/logs.go:25 go.opentelemetry.io/collector/consumer.ConsumeLogsFunc.ConsumeLogs go.opentelemetry.io/collector/consumer@v0.101.0/logs.go:25 go.opentelemetry.io/collector/internal/fanoutconsumer.(*logsConsumer).ConsumeLogs go.opentelemetry.io/collector@v0.101.0/internal/fanoutconsumer/logs.go:62 go.opentelemetry.io/collector/receiver/otlpreceiver/internal/logs.(*Receiver).Export go.opentelemetry.io/collector/receiver/otlpreceiver@v0.101.0/internal/logs/otlp.go:41 go.opentelemetry.io/collector/pdata/plog/plogotlp.rawLogsServer.Export go.opentelemetry.io/collector/pdata@v1.8.0/plog/plogotlp/grpc.go:88 go.opentelemetry.io/collector/pdata/internal/data/protogen/collector/logs/v1._LogsService_Export_Handler.func1 go.opentelemetry.io/collector/pdata@v1.8.0/internal/data/protogen/collector/logs/v1/logs_service.pb.go:311 go.opentelemetry.io/collector/config/configgrpc.(*ServerConfig).toServerOption.enhanceWithClientInformation.func9 go.opentelemetry.io/collector/config/configgrpc@v0.101.0/configgrpc.go:439 go.opentelemetry.io/collector/pdata/internal/data/protogen/collector/logs/v1._LogsService_Export_Handler go.opentelemetry.io/collector/pdata@v1.8.0/internal/data/protogen/collector/logs/v1/logs_service.pb.go:313 google.golang.org/grpc.(*Server).processUnaryRPC google.golang.org/grpc@v1.64.0/server.go:1379 google.golang.org/grpc.(*Server).handleStream google.golang.org/grpc@v1.64.0/server.go:1790 google.golang.org/grpc.(*Server).serveStreams.func2.1

Collector version

v.0.101.0

Environment information

Environment

Container image: otel/opentelemetry-collector-contrib:0.101.0

OpenTelemetry Collector configuration

No response

Log output

No response

Additional context

No response

github-actions[bot] commented 1 week ago

Pinging code owners:

evan-bradley commented 1 week ago

Thanks for reporting this @Marty1703. I checked and this happens because we expect that ParsJSON parses and returns a map. I think it's fair to expect it should return whatever type matches the top-level object in the JSON string, or at a minimum that we document this limitation. The docs do cover that we return a pcommon.Map, but not that other top-level types aren't somehow coerced into a map.

TylerHelmuth commented 1 week ago

For reference, stanza has a separate JSON Array parser for these situations