-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Loki Exporter - Adding a feature for loki exporter to encode JSON for log entry #5846
Conversation
@crearys I recreated your PR, added some little changes to "finish" a v1, so even if it's probably not perfect it covers probably almost 100% of use cases. In the meantime I try to find a maintener for the exporter, and be able to merge ! |
PR in draft, I'm searching for a Loki maintainer on "loki-dev" slack |
@gillg Apologies for the slow reply, i've been really busy recently. I totally agree as we are still using a forked version with this feature. It would be good to get this merged once we have a new maintainer. |
@jpkrohling proposed to adopt the orphan exporter Loki 👏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple of minor items, but looks good to me overall!
|
||
extensions: | ||
health_check: | ||
pprof: | ||
zpages: | ||
memory_ballast: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you actually need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, but was to be consistent with the previous exemple. We can remove it if you think it's better.
Does memory ballast shouldn't always be used when we receive pushed data like logs ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We recommend that people always use things like the batch processor and memory ballast, but I find it confusing to add something not relevant to what is being demonstrated.
exporter/lokiexporter/exporter.go
Outdated
@@ -195,9 +210,20 @@ func (l *lokiExporter) convertAttributesToLabels(attributes pdata.AttributeMap, | |||
return ls | |||
} | |||
|
|||
func convertLogToLokiEntry(lr pdata.LogRecord) *logproto.Entry { | |||
func convertLogToLokiEntry(lr pdata.LogRecord, res pdata.Resource) (*logproto.Entry, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function's name is now a bit strange. How about renaming it to convertLogToPlainEntry
or convertLogToStringEntry
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, why not convertLogBodyToEntry
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like "Body" needs the reader to have a bigger context than simply "String", for instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hum, I don't understand you you mean, but by the way.... I'm thinking the body can be a complex structure in OTEL, I already had a case here #4955
I was trying to use the syslog receiver
, but all structured data are put in the body instead of attributes, and attributes are empty.
As opposite, fluentforward receiver
set an empty body (except if it finds an arbitrary key "message" or "log") and put all structured log data in attributes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, sounds good, convertLogBodyToEntry
it is!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK !
But does lr.Body().StringVal()
will handle a structured body ? (case where you use syslog receiver)
If not we need to serialize it anyway :/
For the JSON encoding case it's implicit, but for this "raw string" output it's not obvious. Does a logfmt serializer exists ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a test and see what happens?
Last question @jpkrohling. With the format "body", the loki log entry will be something like : Note : Indexed labels are not related to the log entry, we create the mapping manualy from pure OTEL attributes and resources. |
No problem with JSON, I prefer when logs are human readable but that seems to be a valid option to push json if we want to keep metadata inside each line. May be we should add another format like |
Thanks @cyriltovena ! |
exporter/lokiexporter/exporter.go
Outdated
@@ -150,6 +178,8 @@ func (l *lokiExporter) logDataToLoki(ld pdata.Logs) (pr *logproto.PushRequest, n | |||
} | |||
} | |||
|
|||
l.logger.Error("some logs has been dropped", zap.Error(errs)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be lost here. Shouldn't you wrap it in a conditional?
} | ||
return &logproto.Entry{ | ||
Timestamp: time.Unix(0, int64(lr.Timestamp())), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious about what is the behavior when the timestamp is bigger than the upper boundary for int64
, given that lr.Timestamp
is a uint64
, assuming that lr.Timestamp
is user input. Not for this PR, as this pattern has been used before in this codebase already.
This PR was marked stale due to lack of activity. It will be closed in 7 days. |
@gillg, do you need any help progressing with this PR? |
Hello, yes I have a lack of time and... I'm sure in fact that the actual body serialization is not valid. It could work as a v1 but knowing it doesn't cover use cases where your body is a complex object and not a simple string. 😕 What do you want ? We assume I just fix remaining details or we target the "perfect" version ? P.S: I can make functional changes, but I'm probably not confortable enought with Go to create many tests for different complex use tests with basic attributes, basic resources, string body, complex body, etc. I don't have any idea how to serialize in a generic way a pdata because it can contains string, AttributeMap, ints, etc. |
I think this is the key: you are adding a feature that solves a problem for you, and it seems reasonable to me. Let's get this first version done, and iterate from there. About further testing: create an issue to track it and assign it to me. I can take a look and contribute some tests, tagging you to review my work. How does that sound? |
This PR was marked stale due to lack of activity. It will be closed in 7 days. |
Closed as inactive. Feel free to reopen if this PR is still being worked on. |
Hello ! |
By the way have you some informations about this otep ? open-telemetry/oteps#188 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good! Just a question, but I think it's ready to be merged.
@cyriltovena, would you like to take a final look? |
…a trace of the reason
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I'll wait until tomorrow afternoon (UTC) to see if @cyriltovena wants to give a final review, otherwise I'll merge this.
Originaly from #3874
Description:
The PR creates a feature for the Loki Exporter that allows you to use a JSON representation of the LogRecord as described by https://developers.google.com/protocol-buffers/docs/proto3#json.
It creates a Loki LogEntry using JSON instead of the current
body
string.The
format
option allows you to choose betweenjson
or thebody
string, the default is the body string.This feature allows us to handle structured logging the Loki exporter and use structured logging in our logging pipeline.
Link to tracking Issue: This may fix the issue: #2529
Testing: TestConvert - Ensuring the json encoding is providing expected responses.
TestJsonLoadConfig - Ensuring the format config option is set correctly.
TestExporter_convertLogtoJsonEntry - Ensuring the Log Entry is converted to a JSON Entry.
Documentation: Comments added to the functions and README options updated.