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

Fix observability #285

Merged
merged 9 commits into from
Nov 14, 2024
Merged

Fix observability #285

merged 9 commits into from
Nov 14, 2024

Conversation

jt-dd
Copy link
Contributor

@jt-dd jt-dd commented Nov 13, 2024

Reworking the observability stack to get metrics, logs and events from all differentes phases of processing.

@jt-dd jt-dd marked this pull request as ready for review November 13, 2024 21:57
@jt-dd jt-dd requested a review from a team as a code owner November 13, 2024 21:57
Comment on lines +141 to +145
if log.GetRunIDFromContext(outer) != "" {
var spanPut ddtrace.Span
spanPut, outer = span.SpanRunFromContext(outer, span.IngestorBlobPull)
defer func() { spanPut.Finish(tracer.WithError(err)) }()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

2 comments (I may miss understanding something):

  • GetRunIDFromContext feels weird to be in the log package?
  • Can't we "automatically" do that in the custom span package directly ? Since you alread set default tags in there ? This would also simplify adding other custom field?

It would simplify that call in every places to only the 2 lines:

spanPut, outer = span.SpanRunFromContext(outer, span.IngestorBlobPull)
defer func() { spanPut.Finish(tracer.WithError(err)) }()

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 a special usecase for the blob. Here it is not to span too many spans (adding a comment).

Where would you prefer GetRunIDFromContext() to be ?

pkg/telemetry/events/events.go Outdated Show resolved Hide resolved
"github.com/DataDog/datadog-go/v5/statsd"
)

const (
DumperRun = "kubehound.dumper.run"
DumperStop = "kubehound.dumper.stop"
EventActionFail = "fail"
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe it would be a nice improvement to use these as a custom EventAction type instead of string.

This way, you can enforce the strings to match your expectation.
The defined api contract is a bit "weird" here imo, as it contains package specific code (PushEventIngestSkip is tied to the Ingestor, directly in its name). I'd not mind if it was is a struct / map "as data" for collocation purpose, but as an exposed API it's couple the 2 packages.

You could refactor all of these individual function into a single one like so (following code not tested) to avoid the duplication for each event and makes it simpler and easier to udpate overall:

type EventAction string

const (
	EventActionFail   = "fail"
	EventActionInit   = "init"
	EventActionStart  = "start"
	EventActionSkip   = "skip"
	EventActionFinish = "finish"
)

func (ea EventAction) Message() string{
	return map2msg[ea]
}

func (ea EventAction) Tags() []string {
	tags := tag.GetDefaultTags(ctx)
	tags = append(tags, fmt.Sprintf("%s:%s", ActionTypeTag, ea))
	return tags 
}
func (ea EventAction) Level() statsd.Level {
	return statsd.Info
}

// Could also be a format stirng template in this case, if needed?
var map2msg = map[EventAction]string{
	EventActionFail = "Ingestor/grpc endpoint init failed",
	EventActionInit = "" //...
	// ...
}

func PushEvent(ctx context.Context, action EventAction) error{
	return kstatsd.Event(&statsd.Event{
		Title:     action.Title(),
		Text:      action.Message(),
		Tags:      action.Tags(),
		AlertType: action.Level(),
	})
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok make sense but some events requires args that needs to be passed. So they will need a custom PushEvent wrapper for those specific.

Copy link
Contributor

@edznux-dd edznux-dd Nov 14, 2024

Choose a reason for hiding this comment

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

I'd think an opt Option or opt ...Option argument (variadic) type would be enough and allow basic definition to not need it (for the variadic version)? But I haven't tried.

(the variadic version has the edge case of multiple option provided, which is a bit more annoying to implement and is probably not worth the hassle here?)

@jt-dd jt-dd requested a review from edznux-dd November 14, 2024 14:54
Copy link
Contributor

@edznux-dd edznux-dd left a comment

Choose a reason for hiding this comment

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

Not a fan of having the "exposed" API with individual actions instead of just calling pushEvent() directly, but 🤷

@jt-dd
Copy link
Contributor Author

jt-dd commented Nov 14, 2024

Not a fan of having the "exposed" API with individual actions instead of just calling pushEvent() directly, but 🤷

As discussed refactor with PushEvent() only exposed.

@jt-dd jt-dd merged commit 2d1e729 into main Nov 14, 2024
8 checks passed
@jt-dd jt-dd deleted the jt-dd/fix-observability branch November 14, 2024 17:21
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.

2 participants