Skip to content

Conversation

@franciscovalentecastro
Copy link
Contributor

@franciscovalentecastro franciscovalentecastro commented May 12, 2025

Description

Created LoggingReceiverMacro and LoggingProcessorMacro to standardize implementation of 3rd party app logging receivers and processors. They work as a "macro" in the sense that after defining a reduced sub-agent (otel or fluent-bit) agnostic definition of a receiver or processor, the "macro" is "expanded/replaced" with a full implementation of a configurable LoggingReceiver or LoggingProcessor. Co-author @quentinmit.

A list of additions in this PR :

  1. Created LoggingReceiverMacro, LoggingProcessorMacro to encapsulate the key elements of a LoggingReceiver, LoggingProcessor, respectively. The "macros" only need a sub-agent (otel or fluent-bit) agnostic definition of the key methods required by the Logging(Receiver|Processor). This definitions help to reduce the redundant code while defining a large number of 3p receivers.

  2. Created RegisterLoggingReceiverMacro and RegisterLoggingProcessorMacro methods which "generate/expand/replace" the "Macro" definitions with a fully implemented LoggingReceiver of LoggingProcessor. Additionally RegisterLoggingFilesProcessorMacro was created to simplify the most common definition of 3P app receivers (files receiver + processors).

  3. Created un-exported loggingReceiverMacroAdapter and loggingProcessorMacroAdapter which adapt the "macro" definitions with a fully implemented LoggingReceiver or LoggingProcessor.

Context

Based on the following :

Related issue

b/401028449

How has this been tested?

Checklist:

  • Unit tests
    • Current Unit Tests are passing.
    • Unit tests do not apply.
    • Unit tests have been added/modified and passed for this PR.
  • Integration tests
    • Current Integration tests are passing.
    • Integration tests do not apply.
    • Integration tests have been added/modified and passed for this PR.
  • Documentation
    • This PR introduces no user visible changes.
    • This PR introduces user visible changes and the corresponding documentation change has been made.
  • Minor version bump
    • This PR introduces no new features.
    • This PR introduces new features, and there is a separate PR to bump the minor version since the last release already.
    • This PR bumps the version.

Component
// Components returns fluentbit components that implement this processor.
// tag is the log tag that should be matched by those components, and uid is a string which should be used when needed to generate unique names.
Components(ctx context.Context, tag string, uid string) []fluentbit.Component
Copy link
Member

Choose a reason for hiding this comment

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

LoggingProcessor can now embed LoggingProcessorMixin instead of duplicating the signature (and you probably should move the comment into the Mixin type to preserve it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. I also embedded LoggingReceiverMixin in LoggingReceiver.

LoggingReceiverTypes.RegisterType(func() LoggingReceiver { return &LoggingReceiverSystemd{} }, platform.Linux)
}

type LoggingCompositeReceiver[R LoggingReceiverMixin, P LoggingMultiProcessorMixin] struct {
Copy link
Member

Choose a reason for hiding this comment

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

I'm struggling a bit with all the similar type names
Do you think you could write a brief comment to describe the different types and how they fit together?

Copy link
Contributor Author

@franciscovalentecastro franciscovalentecastro May 14, 2025

Choose a reason for hiding this comment

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

I added comments to the definitions of LoggingReceiverMixin, LoggingProcessorMixin, LoggingMultiProcessor and LoggingCompositeReceiver. This may need more work/added detail.

I also updated the PR description with more details about the types and naming used.

}

// LoggingReceiverMixin implements all the methods required to describe a logging receiver pipeline.
type LoggingReceiverMixin interface {
Copy link
Member

Choose a reason for hiding this comment

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

LoggingReceiverMixin -> InternalLoggingReceiver

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

}

// LoggingProcessorMixin implements the methods required to define a logging receiver pipeline.
type LoggingProcessorMixin interface {
Copy link
Member

Choose a reason for hiding this comment

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

LoggingProcessorMixin -> InternalLoggingProcessor

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

}

// LoggingMultiProcessorMixin implements the methods required to describe a pipeline with one or more log processors.
type LoggingMultiProcessorMixin interface {
Copy link
Member

Choose a reason for hiding this comment

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

LoggingMultiProcessorMixin -> LoggingProcessorMacro, the idea being that it's a C-style macro to transform Ops Agent processor config into Ops Agent processor(s) config

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

apps/flink.go Outdated
confgenerator.LoggingReceiverTypes.RegisterType(func() confgenerator.LoggingReceiver {
return &confgenerator.LoggingCompositeReceiver[LoggingReceiverMixinFlink, LoggingMultiProcessorMixinFlink]{}
})
confgenerator.LoggingProcessorTypes.RegisterType(func() confgenerator.LoggingProcessor {
Copy link
Member

Choose a reason for hiding this comment

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

What if we add a .RegisterMacro method, to be used something like

confgenerator.LoggingProcessorTypes.RegisterMacro(&LoggingProcessorMacroFlink{})

Then that method can wrap the processor in a local type that turns it into a LoggingProcessor, but that wrapping type doesn't have to leak out into the rest of Ops Agent

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for all the guidance, pair-programming and offline discussions.

Done! The methods implemented are currently :

  • RegisterLoggingCompositeReceiverMacro
  • RegisterLoggingProcessorMacro

}

// LoggingMultiProcessor represents a pipeline that consists of one or more log processors.
type LoggingMultiProcessor[P LoggingMultiProcessorMixin] struct {
Copy link
Member

Choose a reason for hiding this comment

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

Let's see if we can make this an unexported internal type (see comment in flink.go)

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 became loggingProcessorMacroAdapter.

// LoggingCompositeReceiver represents a pipeline that consists of one log receiver & one or more log processors.
type LoggingCompositeReceiver[R LoggingReceiverMixin, P LoggingMultiProcessorMixin] struct {
ConfigComponent `yaml:",inline"`
MultiProcessorMixin P `yaml:",inline"`
Copy link
Member

Choose a reason for hiding this comment

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

Why does this take a MultiProcessorMixin instead of just taking an InternalLoggingProcessor and deferring to that processor to construct the components?

Copy link
Contributor Author

@franciscovalentecastro franciscovalentecastro May 16, 2025

Choose a reason for hiding this comment

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

I created a LoggingComponentMacro (which has a []InternalLoggingProcessor) struct to build a LoggingCompositeReceiver with the following two structs :

// LoggingComponentMacro is a logging component that generates other
// Ops Agent receiver and/or processors as its implementation.
type LoggingComponentMacro interface {
Type() string
// Processors returns slice of logging processors. This is an intermediate representation before sub-agent specific configurations.
Processors(ctx context.Context) []InternalLoggingProcessor
Receiver(ctx context.Context) InternalLoggingReceiver
}

// loggingCompositeReceiverMacroAdapter represents a pipeline that consists of one log receiver & one or more log processors.
type loggingCompositeReceiverMacroAdapter[LCM LoggingComponentMacro] struct {
ConfigComponent `yaml:",inline"`
ComponentMacro LCM `yaml:",inline"`
}

@franciscovalentecastro franciscovalentecastro changed the title [confgenerator] Create LoggingCompositeReceiver and update flink. [confgenerator] Create LoggingComponentMacro to generate 3p receivers implementation and update flink. May 16, 2025
@franciscovalentecastro franciscovalentecastro changed the title [confgenerator] Create LoggingComponentMacro to generate 3p receivers implementation and update flink. [confgenerator] Create LoggingCompositeReceiverMacro to generate 3p receivers implementation and update flink. May 16, 2025
@franciscovalentecastro franciscovalentecastro changed the title [confgenerator] Create LoggingCompositeReceiverMacro to generate 3p receivers implementation and update flink. [confgenerator] Create Logging to generate 3p receivers implementation and update flink. May 20, 2025
@franciscovalentecastro franciscovalentecastro changed the title [confgenerator] Create Logging to generate 3p receivers implementation and update flink. [confgenerator] Create LoggingReceiverMacro to generate 3p receivers implementation and update flink. May 20, 2025
@franciscovalentecastro franciscovalentecastro changed the title [confgenerator] Create LoggingReceiverMacro to generate 3p receivers implementation and update flink. [confgenerator] Create LoggingReceiverMacro and LoggingProcessorMacro to generate 3p receivers implementation and update flink. May 20, 2025
@franciscovalentecastro franciscovalentecastro force-pushed the fcovalente-composite-receiver branch 4 times, most recently from ddd3dee to c3f087b Compare May 21, 2025 16:37
@franciscovalentecastro franciscovalentecastro force-pushed the fcovalente-composite-receiver branch from c3f087b to ae4e1ed Compare May 21, 2025 17:13
@franciscovalentecastro franciscovalentecastro added the kokoro:force-run Forces kokoro to run integration tests on a CL label May 23, 2025
@stackdriver-instrumentation-release stackdriver-instrumentation-release removed the kokoro:force-run Forces kokoro to run integration tests on a CL label May 23, 2025
@franciscovalentecastro franciscovalentecastro merged commit db2f3f0 into master May 26, 2025
73 of 74 checks passed
@franciscovalentecastro franciscovalentecastro deleted the fcovalente-composite-receiver branch May 26, 2025 17:28
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.

4 participants