-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fluentbit OpenTelemetry Output Pipeline/Plugin doesnt format fields properly #8359
Comments
Thank you for opening this issue! I spent the last hour or so using different filter plugins (e.g., |
We where experience the same behavior forwarding logs and metrics from FluentBit to Victoria Matrics and Logs, and VM/VL would not accept the data and discarded it !! |
we are taking a look at this, thanks for raising the issue |
I am triaging this, and I have a question about the position of the extra fields: (copy pasting the expected behavior you posted above) {
"body": {
"message": "This is a test log message for abc application",
},
"clientIp": "111.222.888",
"loglevel": "INFO",
"service": "helloworld",
"instrumentation.name": "",
"instrumentation.version": "",
"observed_timestamp": 0,
"testtag": "fluentbit",
"severity_text": "",
"span_id": "9c1544cc4f7ff369",
"timestamp": "2024-01-08 18:37:08.150",
"trace_id": "7ada6c95a1bd243fa9013cab515173a9"
} isn't expected that the content be inside |
Thank you for looking into this @edsiper! According to the example log records in the Log Data Model the log message itself should be under The example given in the linked page is: {
"Timestamp": 1586960586000, // JSON needs to make a decision about
// how to represent nanoseconds.
"Attributes": {
"http.status_code": 500,
"http.url": "http://example.com",
"my.custom.application.tag": "hello",
},
"Resource": {
"service.name": "donut_shop",
"service.version": "semver:2.0.0",
"k8s.pod.uid": "1138528c-c36e-11e9-a1a7-42010a800198",
},
"TraceId": "f4dbb3edd765f620", // this is a byte sequence
// (hex-encoded in JSON)
"SpanId": "43222c2d51a7abe3",
"SeverityText": "INFO",
"SeverityNumber": 9,
"Body": "20200415T072306-0700 INFO I like donuts"
} |
thanks @sudomateo so my understanding by using the examples provided above is that we are compatible but some implementations don't allow structured content inside the body. In the log model there is also this example: {
"Timestamp": 1586960586000,
...
"Body": {
"i": "am",
"an": "event",
"of": {
"some": "complexity"
}
}
} |
This is my understanding as well. There was some discussion about this in the past at open-telemetry/opentelemetry-specification#1613. The consensus there seems to favor the use of From my perspective there seems to be 2 aspects to this.
I believe the original ask of this issue is to support the 2nd point. |
so my understanding is similar to @sudomateo. There are predefined attributes (such as spand_id, trace_id, SeverityText, etc) that should be at the SAME level as body (not within body). Body should just be the body of the log record, aka the message. Body is of type "any" so it can be a simple string or a map, but in either case it should just contain the log message. Attributes is a map and for adding "custom" fields that are not defined in the data model. Resource is also a map and would contain info about the source of the log however fluentbit otel output plugin does not seem to yet support adding "resource" field. This is the best document ive found on log data model is here logs-data-model. All frontend applications I have sent logs too (using flentbit) expect the logs to be structured as defined on that page. The example @sudomateo gave above would be a valid example. The only thing I would add to his example is that the body can be one of the 2 ways below, both are technically valid according to otel.
I would also like to note that it seems the fluenbit otel output plugin supports the ability to add attributes, however whenever i tried to define some, it seemed they did not get added nor sent. For example, if i added the following configuration:
Then I would expect my "payload" to contain an attributes section containing "status_code" : "500", however this did not happen. But maybe the add_label field is not intended for this? If not, then im not sure what add_label is for? Also, if not, then I would suggest adding the ability to add attributes. |
@cb645j from what I understand the existing
I'm not sure how metrics and logs are differentiated internally in Fluent Bit, but I just wanted to note that I also tried |
I agree. Therefore, it would be nice if fluentbit added support for adding attributes. However, in my opinion this is lower priority. Fixing the overall structure is the main priority related to this issue. |
@edsiper any update here? |
There are a couple of use cases, I am looking to get your feedback and confirm expectations: Inside Fluent Bit, all messages are structured, something that started as a
would make sense to pre-define certain keys that can be part of the note: putting attributes handling in a side for a moment to brainstorm in the logic to handle the expected output structure |
Fluent Bit v2.1.0 and later updated the event format to add support for metadata.
Depending on what this metadata is meant to be used for, I can see a use case where the metadata is used to hold event attributes.
There's precedent for this. For example, the
I can see a case for both sides here. If the event only contains one key, then it's easy to want to assume that key must contain the event body. However, how would such an event be distinguished from a structured event of only one key? This is where I start to lean towards some new configuration option (i.e.,
Similar concerns as above. How does one differentiate between a structured event that should completely go inside the This is just my opinion. Curious to hear what others think. |
@sudomateo thanks for your feedback. I came up with something similar, I am working in a POC of this logic, I will keep you posted. |
I believe the most important thing to start with is getting the span_id, trace_id, and other predefined fields in the correct structure (outside of body). Too me, when there is more than one key, the key that goes in the body is the key that represents the log message (maybe let user define in settings what that key value is). Then, keys that are timestamp, SpanId, TraceId, SeverityText, severitynumber would all be their own element. Then, the remaining keys would go inside attributes. |
@sudomateo yes, except if the key is something like span-id or trace-id, or etc. Those should NOT go in attributes, they should be their own element (at the same level as body, attributes). |
some updates:
I will ping you here once I push the branch so you can give it a try |
Thanks, please share the branch once pushed. Also, can you confirm that you are setting the trace-id and span-id as separate root fields NOT nested within body or attributes?? I.e.
|
Thanks for working on this @edsiper! Let us know when you have something ready for us to test. To echo @cb645j, I agree that Fluent Bit should populate and/or expose a mechanism to populate all the top-level fields in the Logs Data Model.
Not just |
…ix #8359) The following patch fix and enhance the OpenTelemetry output connector when handling log records. In Fluent Bit world, we deal with ton of unstructured log records which comes from variety of sources, or just simply raw text files. When converting those lines to structured messages, there was no option to define what will be the log body and log attributes and everything is packaged inside log body by default. This patch enhance the previous behavior by allowing the following: - log body: optionally define multiple record accessor patterns that tries to match a key or sub-key from the record structure. For the first matched key, it's value is used as part of the body content. If no matches exists, the whole record is set inside the body. - log attributes: if the log record contains native metadata, the keys are added as OpenTelemetry Attributes. if the log body was populated by using a record accessor pattern as described above, the remaining keys that were not used are added as attributes. To achieve the desired new behavior, the configuration needs to use the new configuration property called 'logs_body_key', which can be used to define multiple record accessor patterns. e.g: pipeline: inputs: - name: dummy metadata: '{"meta": "data"}' dummy: '{"name": "bill", "lastname": "gates", "log": {"abc": {"def":123}, "saveme": true}}' outputs: - name: opentelemetry match: '*' host: localhost port: 4318 logs_body_key: $name logs_body_key: $log['abc']['def'] In the example above, the dummy input plugin will generate a record with metadata, in the output side, the plugin will lookup in order for $name and then $log['abc']['def']. $name will match so 'bill' will become the value of the body and the remaining content as attributes. Here is the output of the vanilla Otel Collector when inspecting the content it receives: Body: Str(bill) Attributes: -> meta: Str(data) -> lastname: Str(gates) -> log: Map({"abc":{"def":123},"saveme":true}) Signed-off-by: Eduardo Silva <[email protected]>
first PR is here: #8491 Please help to review the behavior based on the "features it adds". |
I also sent another PRs. They are to forward OTLP.
|
I tested @edsiper's changes and wrote up my notes in #8491 (comment). |
I did not get a chance to test but i reviewed @sudomateo notes and results and pretty much agree with those. I see the PR has been merged. When will it be available in a version? |
@sudomateo how did you go about compiling and creating a new image? how did you compile? which dockerfile did you use? |
I followed the Build from Scratch instructions. cd build
cmake ..
make Then you'll have |
@edsiper which release/image will this be part of? |
@sudomateo I got pass the cmake.. step but then when i do make i get $ make I dont see a make file in /build ?? |
After the
Seems like your |
@sudomateo thanks for your response. Its possible cmake didnt complete but it appeared like it did... I dont see a make file in your /build either?? This is the contents of my /build
|
@sudomateo my cmake ends with:
so i assumed it completed successfully....?? The only things i see in to that look alarming are these
|
That is weird. I was building on a macOS machine with an Apple Silicon chip. I got errors when I didn't have |
Possibly, let me try installing. its just odd that the cmake completes without errors. It does look like im missing a couple of directories that you have. what directory are the make files in? im assuming these get generated or download when you run cmake |
@edsiper when will this be available in a release? I.e. when will a new image containing this be available??? |
1 similar comment
@edsiper when will this be available in a release? I.e. when will a new image containing this be available??? |
A little late to the party here, but wanted to say very nice work on this. I've been using the Fluent output and using Otel's fluent forward receiver which places all of the log records under the "resources" key. This is AFAICT an undocumented feature of the receiver and it also requires complex restructuring pipelines to get all of the attributes/resources in the right places. To build off of this capability it would be awesome to have support for automatically parsing records supplied by the Kubernetes Filter into resource attributes that match those provided by OpenTelemtry's k8sattributes processor. |
@kevarr Thank you. Yes, i experienced with the approach you described however I want to be able to streamline and simplify the process but just being able to use fluentbit (without a collector) to export in otel format. It seems a lot of people are interested in this. Its unfortunate that the fluentit otel_ouput does not work properly and support all of the otel fields and its very difficult to get the owners/contributors of fluentbit to make changes and respond. I have a follow up ticket here for the things that are still missing #8552 |
Issue:
When using the OpenTelemetry Output Pipeline/Plugin to send logs to an opentelemetry endpoint, the output json/payload/fields are not formatted correctly. They should be formatted according to the opentelemetry specifications. As a result, opentelemetry is unable to process the request, from fluentbit, correctly.
Fluentbit Logs showing logs being sent to opentelemtry endpoint:
[36] ebiz: [[1704434606.150000000, {}], {"message"=>"This is a test log message for abc application", "loglevel"=>"INFO", "service"=>"helloworld", "clientIp"=>"111.222.888", "timestamp"=>"2024-01-08 18:37:08.150", "testtag"=>"fluentbit", "trace_id"=>"7ada6c95a1bd243fa9013cab515173a9", "span_id"=>"9c1544cc4f7ff369"}]
[2024/01/08 18:37:10] [debug] [upstream] proxy returned 200
[2024/01/08 18:37:10] [debug] [http_client] flb_http_client_proxy_connect connection #32 connected to myproxy.com:8080.
[2024/01/08 18:37:10] [debug] [upstream] proxy returned 200
[2024/01/08 18:37:10] [debug] [http_client] flb_http_client_proxy_connect connection #31 connected to myproxy.com:8080.
[2024/01/08 18:37:10] [debug] [upstream] KA connection #32 to myproxy.com:8080 is connected
[2024/01/08 18:37:10] [debug] [http_client] not using http_proxy for header
[2024/01/08 18:37:10] [debug] [upstream] KA connection #31 to myproxy.com:8080 is connected
[2024/01/08 18:37:10] [debug] [http_client] not using http_proxy for header
[2024/01/08 18:37:10] [ info] [output:opentelemetry:opentelemetry.1] ingest.privateotel.com:443, HTTP status=200
My fluentbit configuration:
My opentelemetry endpoint receives the request formatted as such:
As you can see above every named pair gets nested under the body. The body should simply contain the log message and all the other fields I choose to send should be nested under "fields". The proper format would looks something like what i have below.
Expected behavior:
To Reproduce
Use a configuration similiar to mine. Generate a log line, extract some fields from that log line including traceid, spanid, timestamp, body, etc. Then use the opentelemetry output and point it to a opentelemetry endpoint.
Your Environment
I am running in a Kubernetes cluster using a daemonset and the configmap above.
The version on fluentbit I am using is 2.1.10.
The image is fluent/fluent-bit:2.1.10-debug
Additional context
Opentelemetry is unable to correctly process all the fields such as traceid and span id since they are not in the proper format schema
For more information on the opentelemetry logging data model and schema, please see below:
Otel logs data model docs
Otel logs data model github
Additional resource
Please fix the issue or if there is something I am doing incorrectly in my fluentbit config then please advise. Thank you.
The text was updated successfully, but these errors were encountered: