Skip to content
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 #3874

Closed
wants to merge 16 commits into from

Conversation

crearys
Copy link
Contributor

@crearys crearys commented Jun 24, 2021

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 between json or the body 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.

@crearys crearys requested review from a team and Aneurysm9 June 24, 2021 15:57
@tigrannajaryan tigrannajaryan requested a review from gramidt June 28, 2021 17:04
@bogdandrutu
Copy link
Member

@gramidt please review

@github-actions
Copy link
Contributor

github-actions bot commented Jul 9, 2021

This PR was marked stale due to lack of activity. It will be closed in 7 days.

@github-actions github-actions bot added the Stale label Jul 9, 2021
@gramidt
Copy link
Member

gramidt commented Jul 9, 2021

I apologize for the delay, @crearys and @bogdandrutu. I was out of the office on vacation and returned to a pile of things to catch up on. I will try to review this PR over the weekend.

@github-actions github-actions bot removed the Stale label Jul 10, 2021
@crearys
Copy link
Contributor Author

crearys commented Jul 12, 2021

@gramidt thanks

@github-actions
Copy link
Contributor

This PR was marked stale due to lack of activity. It will be closed in 7 days.

@github-actions github-actions bot added the Stale label Jul 20, 2021
@@ -135,7 +135,19 @@ func (l *lokiExporter) logDataToLoki(ld pdata.Logs) (pr *logproto.PushRequest, n
continue
}
labels := mergedLabels.String()
entry := convertLogToLokiEntry(log)
var entry *logproto.Entry
if l.config.Format == "json" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the decision on format is not made at runtime, but rather at config time, what are your thoughts on making this decision early on and mapping the appropriate method ahead of time? This would remove the additional check per record.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gramidt I have just pushed a new commit following your comments.

@gramidt
Copy link
Member

gramidt commented Jul 28, 2021

@crearys - Looks like there's some linting and unit test issues. Could you address those?

@gillg
Copy link
Contributor

gillg commented Jul 28, 2021

Does anyone seen my comments ? Mostly about nested structures supported or not by loki with pipe search / grafana in vizualization panel. Are you sure it's ok ?

At otel-collector side can we map atttributes.attr1 to a label ?

EDIT: Sorry my review was never submitted ! 😅

TraceID: lr.TraceID().HexString(),
SpanID: lr.SpanID().HexString(),
Severity: lr.SeverityText(),
Attributes: tracetranslator.AttributeMapToMap(lr.Attributes())}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you created a full structure, why not add "Resources" ? Maybe conditionaly ?

}

func exampleJson() string {
jsonExample := `{"name":"name","body":"Example log","traceid":"01020304000000000000000000000000","spanid":"0506070800000000","severity":"error","attributes":{"attr1":"1","attr2":"2"}}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To follow some logic and to be more explicit on loki side, why not prefix your arbitrary keys (name, body, traceid...) by someting like "otel_collector_lokiexporter_" ?
It can avoid confusion with keys in logs received by another channel than otel collector for exemple.

I would prefer use "otel.collector.lokiexporter." to be more consistent with OTEL but if you apply | json on it, loki replace all points by underscores anyway at the end...

@@ -44,6 +44,8 @@ The following settings can be optionally configured:

- `headers` (no default): Name/value pairs added to the HTTP request headers.

- `format` (default = body): Set the log entry line format. This can be set to 'json' (the entire json encoded log record) or 'body' (the log record body field as a string).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it, finaly it's not too intrusive as potential big change !

TraceID: lr.TraceID().HexString(),
SpanID: lr.SpanID().HexString(),
Severity: lr.SeverityText(),
Attributes: tracetranslator.AttributeMapToMap(lr.Attributes())}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about nested structures on Grafana / Loki ?
In my memories I tested it and it was not working as expected. I'm not sure if loki is able to do something like {} | json | attributes.attr1 == "xxx" and on Grafana log pannel I think nested objects are not correctly rendered.

Does anyone can confirm ?
Do you think attributes could be flatened at json root (maybe with a key prefix) ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Working on logs enriched by a resourcedetector processor, I confirm the Resources should be converted to structured logs data !
In theory some keys could be the same in attributes and resources (even if it doesn't makes sense...) so convertLogToLokiEntry should prefix them by something in my opinion.

@crearys
Copy link
Contributor Author

crearys commented Jul 29, 2021

@gillg To respond to all your comments. In grafana you can query the nested structures using {} | json | attributes_attr1="debug" . Around the flat JSON structure i think there needs to be a consensus on what json format we want to use. For this PR we had only considered encoding the log record, creating a flat json structure will need a different encoding method and could possibly be added as another format.

@gillg
Copy link
Contributor

gillg commented Jul 29, 2021

@gillg To respond to all your comments. In grafana you can query the nested structures using {} | json | attributes_attr1="debug" .

Ok, if I understand, loki makes a kind of native flattening on your nested JSON structure. So it "saves" the problem, but maybe it consumes more resources at query time ? @gramidt do you know if there is a notable impact ? Are we safe doing nothing at otel collector side and let's loki parse/flatten the json ?
Can we use the same notation on otel config ?

loki:
  labels:
    attributes:
      # Allowing 'severity' attribute and not providing a mapping, since the attribute name is a valid Loki label name.
      severity: ""
      http.status_code: "http_status_code" # here http.status_code is not a nested object but just a key

Around the flat JSON structure i think there needs to be a consensus on what json format we want to use. For this PR we had only considered encoding the log record, creating a flat json structure will need a different encoding method and could possibly be added as another format

As Loki takes keys of each nested structures and creates a flat structure with underscores we could do the same thing to help its work. It's just an idea.

And about "unprefixed" keys like name, body, severity, etc, it's less a problem if we keep them as it without a consensus.

@github-actions github-actions bot removed the Stale label Aug 1, 2021
@github-actions
Copy link
Contributor

This PR was marked stale due to lack of activity. It will be closed in 7 days.

@github-actions
Copy link
Contributor

github-actions bot commented Sep 2, 2021

This PR was marked stale due to lack of activity. It will be closed in 7 days.

@github-actions github-actions bot added the Stale label Sep 2, 2021
@bogdandrutu bogdandrutu removed the Stale label Sep 3, 2021
@github-actions
Copy link
Contributor

This PR was marked stale due to lack of activity. It will be closed in 7 days.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 1, 2021

This PR was marked stale due to lack of activity. It will be closed in 7 days.

@github-actions github-actions bot added the Stale label Oct 1, 2021
@crearys
Copy link
Contributor Author

crearys commented Oct 6, 2021

@gramidt updated for 0.36.0

@gramidt
Copy link
Member

gramidt commented Oct 6, 2021

@slim-bean @crearys - Would either of you be interested in becoming the new owner of the Loki exporter? My priorities have shifted and I'm unable to allocate the necessary time to be a good maintainer.

@bogdandrutu bogdandrutu removed the Stale label Oct 6, 2021
@gillg
Copy link
Contributor

gillg commented Oct 11, 2021

A Loki exporter maintener is really needed :/
Probably a Loki core team member would be great to make the good choices according to Loki architecture.

Moreover with this PR we are probably not so far from a final good V1.

@github-actions
Copy link
Contributor

This PR was marked stale due to lack of activity. It will be closed in 7 days.

@bogdandrutu
Copy link
Member

@crearys @gillg @gramidt closing this since we don't have an owner of the component. Please find a good new owner and then reopen the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants