-
Notifications
You must be signed in to change notification settings - Fork 31
cmd/trace-agent: cleanup code related to APM events. #506
Conversation
constants/sampling.go
Outdated
package constants | ||
|
||
// SamplingPriorityKey is the key of the sampling priority value in the metrics map of the root span | ||
const SamplingPriorityKey = "_sampling_priority_v1" |
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.
^ Regarding this file, I added this to fix some cyclic imports. Happy to move this somewhere else that also works 😄
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.
Let's move it into model
where it originally was before I plucked it out, as discussed.
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 a really nice change. I've just added some suggestions (ideas) around naming and exporting/unexporting stuff.
constants/sampling.go
Outdated
package constants | ||
|
||
// SamplingPriorityKey is the key of the sampling priority value in the metrics map of the root span | ||
const SamplingPriorityKey = "_sampling_priority_v1" |
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.
Let's move it into model
where it originally was before I plucked it out, as discussed.
event/extractor/analyzed.go
Outdated
@@ -0,0 +1,52 @@ | |||
package eventextractor |
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.
Let's just have one main package event
, as discussed.
event/extractor/analyzed.go
Outdated
|
||
// AnalyzedExtractor is an event extractor that extracts APM events from traces based on | ||
// `(service name, operation name) => sampling ratio` mappings. | ||
type AnalyzedExtractor struct { |
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'd like to suggest calling it like this:
// ratioExtractor extracts APM events from traces based on `(service name, operation name) => sampling ratio`
// mappings.
type ratioExtractor struct {
What do you think? The word analysed was always a bit confusing to me. But maybe I'm misunderstanding something.
event/extractor/analyzed.go
Outdated
|
||
// NewAnalyzed returns an APM event extractor that extracts APM events from a trace following the provided | ||
// extraction rates for any spans matching a (service name, operation name) pair. | ||
func NewAnalyzed(analyzedSpansByService map[string]map[string]float64) *AnalyzedExtractor { |
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.
If this is going back into a main event
package, it will probably sound nice like this:
event.NewRatioExtractor
Unless you think "analyzed" is better for some reason, which is fine by me. I just don't understand why this word is used, given that it doesn't appear in the documentation. What was analyzed (past tense) ?
event/extractor/analyzed_legacy.go
Outdated
|
||
// LegacyAnalyzedExtractor is an event extractor that extracts APM events from traces based on `serviceName => sampling | ||
// ratio` mappings. | ||
type LegacyAnalyzedExtractor struct { |
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.
Maybe this could also just be legacyExtractor
?
event/extractor/analyzed_legacy.go
Outdated
// LegacyAnalyzedExtractor is an event extractor that extracts APM events from traces based on `serviceName => sampling | ||
// ratio` mappings. | ||
type LegacyAnalyzedExtractor struct { | ||
analyzedRateByService map[string]float64 |
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 we need the word "analyzed"? Could it maybe simply be "rateByService"?
event/extractor/analyzed_legacy.go
Outdated
|
||
// inspect the WeightedTrace so that we can identify top-level spans | ||
for _, span := range t.WeightedTrace { | ||
if s.shouldAnalyze(span) { |
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.
From here I take it that the word analyze is meant for the future, as in: should the backend analyze this? Right? In that case we can remove the word "analyzed" from all the structs, etc. Here it makes sense, on this method.
event/extractor/disabled.go
Outdated
type DisabledExtractor struct{} | ||
|
||
// NewDisabled returns a new APM event extractor that does not extract any events. | ||
func NewDisabled() *DisabledExtractor { |
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 could just be NoopExtractor
if you like, or NewDisabledExtractor
(the longer version)
event/extractor/extractor.go
Outdated
// Extractor extracts APM event spans from a trace. | ||
type Extractor interface { | ||
// Extract extracts APM event spans from the given weighted trace information and returns them. | ||
Extract(t model.ProcessedTrace, sampledTrace bool) []*model.APMEvent |
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 really like this! A lot! I think this is a great idea. For this reason, I'd like to make this the main interface to interact with this package. What do you think? This means:
- Make all
Extractor
implementations (noopExtractor
,ratioExtractor
andlegacyExtractor
) unexported. - Keep all constructors exported (
NewRatioExtractor
,NewLegacyExtractor
andNoopExtractor
) and have them all return anExtractor
focusing the documentation about how they work on top of each constructor.
I think this will give for a great package. Having this interface will make a lot of sense then.
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.
One last thing here: is there any way we can get rid of the second parameter? Is it needed? Wasn't this trace already sampled at this point? Or, would it make sense to include it into the ProcessedTrace
struct instead? I think in your follow-up PR there can be a middle value (no decision) where the trace has neither been considered nor disconsidered yet.
event/extractor/extractor.go
Outdated
} | ||
|
||
// FromConf creates a new APM event extractor based on the provided agent configuration. | ||
func FromConf(conf *config.AgentConfig) Extractor { |
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 wondering if this is the place to have this? I'm a bit skeptical about passing around the AgentConfig
. It always seemed to me that this config was meant for the agent itself only. Maybe this logic belongs in there? (currently cmd/trace-agent
)?
b07d45f
to
20efb7e
Compare
20efb7e
to
ff459b9
Compare
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 a fantastic clean-up. So much better! ❤️And thanks for fixing the sneaky problem with missing events for un-sampled traces.
Added some comments but none are important to me, just nits and praises.
Feel free to merge whenever you like, but when you do, please squash and use the PR title as the commit message.
@@ -191,7 +169,7 @@ func (a *Agent) Process(t model.Trace) { | |||
ts := a.Receiver.Stats.GetTagStats(info.Tags{}) | |||
|
|||
// Extract priority early, as later goroutines might manipulate the Metrics map in parallel which isn't safe. | |||
priority, hasPriority := root.Metrics[sampler.SamplingPriorityKey] | |||
priority, hasPriority := root.GetSamplingPriority() |
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.
👍
@@ -65,7 +43,7 @@ type Agent struct { | |||
// tags based on their type. | |||
obfuscator *obfuscate.Obfuscator | |||
|
|||
sampledTraceChan chan *writer.SampledTrace | |||
tracePkgChan chan *writer.TracePackage |
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.
❤️
defer watchdog.LogOnPanic() | ||
// Everything is sent to concentrator for stats, regardless of sampling. | ||
a.Concentrator.Add(pt) | ||
}() | ||
}(pt) |
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.
💯
return | ||
|
||
if sampled { | ||
pt.Sampled = sampled |
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 can be both inside the if
and outside. Doesn't really matter, right? 😄
@@ -0,0 +1,11 @@ | |||
package event |
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.
Would be nice to document this package. It'd provide a nice opportunity to explain what events are in APM.
writer/trace_writer.go
Outdated
Transactions []*model.Span | ||
// TracePackage represents the result of a trace sampling operation. | ||
// | ||
// If a trace was sampled, then Trace will be set to that trace. Otherwise, it will be nil. |
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.
These two lines seem like they would be destined above each of the fields in the struct below 😊
type SampledTrace struct { | ||
Trace *model.Trace | ||
Transactions []*model.Span | ||
// TracePackage represents the result of a trace sampling operation. |
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'd add here (if you think it helps) that "A package can still be valid when Trace is nil
if it contains Events. This happens when a trace wasn't sampled but events might have been."
writer/trace_writer.go
Outdated
// If a trace was sampled, then Trace will be set to that trace. Otherwise, it will be nil. | ||
// If events were extracted from a trace, then Events will be populated from these events. Otherwise, it will be empty. | ||
type TracePackage struct { | ||
Trace *model.Trace |
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.
It feels so unusual for this to be a pointer (to a slice, which is already technically a pointer).
writer/trace_writer.go
Outdated
return s.Trace == nil && len(s.Transactions) == 0 | ||
// Empty returns true if this TracePackage has no data. | ||
func (s *TracePackage) Empty() bool { | ||
return s.Trace == nil && len(s.Events) == 0 |
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 wonder why this wasn't len(s.Trace) == 0
but it's fine.
writer/trace_writer_test.go
Outdated
func randomSampledTrace(numSpans, numTransactions int) *SampledTrace { | ||
if numSpans < numTransactions { | ||
panic("can't have more transactions than spans in a RandomSampledTrace") | ||
func randomSampledTrace(numSpans, numEvents int) *TracePackage { |
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.
s/randomSampledTrace/randomTracePackage/g
fe99e85
to
66cd02a
Compare
Move most of the code dealing with event extraction into its own package and rename samplers to extractors.
Also, change most references of transactions into events following the documented nomenclature.
This sets the ground for #508