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

Add an otelcol.connector.spanlogs flow component #4713

Conversation

ptodev
Copy link
Contributor

@ptodev ptodev commented Aug 4, 2023

PR Description

This is the flow mode equivalent to static mode's automatic_logging processor.

Which issue(s) this PR fixes

Fixes #4261

Notes to the Reviewer

  • Are we sure otelcol.processor.spanlogs is a good name for this?
  • Initially I wanted to reuse as much code as possible between static and flow modes. Later I gave up on this. I don't think it's very important.
  • The usage of []any in the original code made it look a bit weird. Since this is a purely otel component which doesn't interact with Loki, I decided to use Otel's pcommon.Map. This is the data structure which span attributes are normally stored in. However, this data structure is inefficient when reading and writing to it, since it's actually an array and we need to traverse it on every insertion. Maybe I should switch to a Go map?

PR Checklist

  • CHANGELOG.md updated
  • Documentation added
  • Tests updated
  • Config converters updated

@ptodev ptodev requested review from a team and clayton-cornell as code owners August 4, 2023 22:33
@ptodev ptodev linked an issue Aug 4, 2023 that may be closed by this pull request
Copy link
Contributor

@clayton-cornell clayton-cornell left a comment

Choose a reason for hiding this comment

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

No changes for docs.

spanLen := ss.Spans().Len()

lastTraceID := ""
for k := 0; k < spanLen; k++ {
Copy link
Collaborator

@mattdurham mattdurham Aug 7, 2023

Choose a reason for hiding this comment

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

Can we do something about this level of indentation, even if its moving to a few different functions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I refactored it now, PTAL.

c.spanKeyVals(keyValues, span)
c.processKeyVals(keyValues, rs.Resource(), svc)

newLogRecord, err := c.createLogRecord(typeSpan, traceID, keyValues)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the only difference in these code blocks the first arg to createLogRecord? If so can we make it a function where you pass in the type?

Copy link
Contributor Author

@ptodev ptodev Aug 15, 2023

Choose a reason for hiding this comment

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

I refactored it now, PTAL.

func (c *consumer) processKeyVals(output pcommon.Map, resource pcommon.Resource, svc string) {
rsAtts := resource.Attributes()

// name
Copy link
Collaborator

Choose a reason for hiding this comment

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

I dont understand this comment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Haha, this is copy pasted from automaticloggingprocessor. You're right that it's unclear. I'll replace it with this:

// Add an attribute with the service name

Copy link
Contributor

@clayton-cornell clayton-cornell left a comment

Choose a reason for hiding this comment

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

Some tweaks to the docs

@ptodev ptodev force-pushed the 4261-flow-alternative-to-static-modes-tracing-automatic_logging-processor branch from 9631895 to af18bf3 Compare August 15, 2023 09:55
@ptodev ptodev force-pushed the 4261-flow-alternative-to-static-modes-tracing-automatic_logging-processor branch 2 times, most recently from 23613eb to b96081a Compare August 21, 2023 10:40
@ptodev ptodev force-pushed the 4261-flow-alternative-to-static-modes-tracing-automatic_logging-processor branch from b96081a to 79b2864 Compare August 24, 2023 15:39
@ptodev ptodev changed the title Add an otelcol.processor.spanlogs flow component Add an otelcol.connector.spanlogs flow component Aug 24, 2023
@ptodev
Copy link
Contributor Author

ptodev commented Aug 24, 2023

Hi @mattdurham - I updated the PR again, and I think it's ready for review now (again 😅 ). This is what I last changed:

  • I renamed the component from "processor" to "connector"
  • I tested this locally and it works - I see logs on Grafana Cloud, and I see labels for the logs too.
  • I added the component to all.go
  • Added an entry to the changelog.

}

func convertOtelMapToSlice(m pcommon.Map) []any {
res := make([]any, 0, m.Len())
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should m.len() be m.len() * 2? Since we are flattening the map?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is true! Well spotted, thank you, I'll change it.

att, ok := rsAtts.Get(name)
if ok {
// name/key val pairs
val := output.PutEmpty(name)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure what we are doing here. So if we find a value in rsAtts, we put an empty value into the output and then copy the empty value to att?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah. It does look weird. The issue is that pcommon.Map doesn't have a function to insert a Value and a Key at the same time, like a PutValue(k string, v Value). These kinds of functions only insert specific types like PutInt(k string, v int64).

I want to insert a Value so that I preserve the original type, and this is the only way to do it as far as I can tell.

In hindsight, I should have just used a map[string]pcommon.Value instead of a pcommon.Map. It would also have been more efficient, since a pcommon.Map is actually just an slice. Inserting to it is slow, because it has to traverse the whole slice to see if the element is already in the map.

I'll add a TODO in the code for this, but for now I hope it's fast enough that a pcommon.Map will do.

// New creates a new otelcol.exporter.spanlogs component.
func New(o component.Options, c Arguments) (*Component, error) {
if c.Output.Traces != nil || c.Output.Metrics != nil {
level.Warn(o.Logger).Log("msg", "non-log output detected; this component only works for log outputs and trace inputs")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this true? Why is Metrics checked if logs are the only output?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

c.Output is the output of a otelcol.exporter.spanlogs component. It can only output logs, so if someone configures it to output metrics or traces, it'll complain via this error message.

Unfortunately, due to the current implementation of consumer.go, we always pass metrics, logs, and traces to each otel component regardless of whether the component supports them. I'll raise a separate issue to find a nicer long term solution to this for components which don't support all 3 telemetry signals.

Copy link
Collaborator

@mattdurham mattdurham left a comment

Choose a reason for hiding this comment

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

A few comments but looking good.

@ptodev ptodev force-pushed the 4261-flow-alternative-to-static-modes-tracing-automatic_logging-processor branch from 91a8250 to 2bd53d2 Compare August 25, 2023 14:07
Copy link
Collaborator

@mattdurham mattdurham left a comment

Choose a reason for hiding this comment

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

Lgtm

@ptodev ptodev force-pushed the 4261-flow-alternative-to-static-modes-tracing-automatic_logging-processor branch from a47454a to 051903e Compare August 25, 2023 14:37
@ptodev ptodev merged commit cc3e80d into main Aug 25, 2023
@ptodev ptodev deleted the 4261-flow-alternative-to-static-modes-tracing-automatic_logging-processor branch August 25, 2023 15:00
@clayton-cornell clayton-cornell added the type/docs Docs Squad label across all Grafana Labs repos label Aug 31, 2023
@github-actions github-actions bot added the frozen-due-to-age Locked due to a period of inactivity. Please open new issues or PRs if more discussion is needed. label Feb 22, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 22, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
frozen-due-to-age Locked due to a period of inactivity. Please open new issues or PRs if more discussion is needed. type/docs Docs Squad label across all Grafana Labs repos
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Flow: Alternative to Static mode's tracing automatic_logging processor
3 participants