Skip to content

Conversation

@mattsains
Copy link
Contributor

Changes

This follows up on #3214 by implementing similar behaviour for including resource attributes in Geneva Logs.

Merge requirement checklist

  • CONTRIBUTING guidelines followed (license requirements, nullable enabled, static analysis, etc.)
  • Unit tests added/updated
  • Appropriate CHANGELOG.md files updated for non-trivial changes
  • Changes in public API reviewed (if applicable)

@github-actions github-actions bot added comp:exporter.geneva Things related to OpenTelemetry.Exporter.Geneva perf Performance related labels Nov 14, 2025
@codecov
Copy link

codecov bot commented Nov 14, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.95%. Comparing base (6a43b08) to head (85e9c53).
⚠️ Report is 7 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3531      +/-   ##
==========================================
+ Coverage   70.92%   70.95%   +0.03%     
==========================================
  Files         430      430              
  Lines       17214    17234      +20     
==========================================
+ Hits        12209    12229      +20     
  Misses       5005     5005              
Flag Coverage Δ
unittests-Exporter.Geneva 53.82% <100.00%> (+0.17%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...Telemetry.Exporter.Geneva/GenevaExporterOptions.cs 90.24% <ø> (ø)
...OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs 87.75% <100.00%> (+0.25%) ⬆️
...rter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs 92.88% <100.00%> (+0.57%) ⬆️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mattsains mattsains force-pushed the logs-resources branch 3 times, most recently from 2f4d319 to 35ccac1 Compare November 17, 2025 17:20
@mattsains mattsains marked this pull request as ready for review November 17, 2025 19:10
@mattsains mattsains requested a review from a team as a code owner November 17, 2025 19:10

Resources.Resource ResourceProvider()
{
return connectionStringBuilder.HonorResourceAttributes ? this.ParentProvider.GetResource() : Resources.Resource.Empty;
Copy link
Member

Choose a reason for hiding this comment

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

is this a simple boolean setting, which, when enabled, will add all resource attributes to the log?

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, it's a connection string-based opt-in feature switch

Copy link
Member

Choose a reason for hiding this comment

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

Got it. I spoke to @rajkumar-rangaraj also, and IMHO, it should be a per-attribute opt-in instead of adding all resource attributes. I understand users can control Resource by limiting things added to Resource, but Resource is not per exporter, so it's possible they need full resource in another exporter but limited one in Geneva, which is impossible to achieve now.

Few reasons why I think this should be enabled on per-resource-attribute basis.

  1. Consistency with other Geneva - elsewhere, this is opt-in on per-attribute basis. eg: OTel Rust
  2. Given GenevaExporter can only operate with a local agent, it is much better for the agent to add most of the resource information itself. (This is quite different than OTLP approach where agent is likely remote and cannot deduce resource information itself)
  3. Payload size limitations - both etw and linux user_events transport have strict hard limit of 64KB, so adding all the resource attributes is not a good idea.
  4. Unlike OTLP/Zipkin exporters, GenevaExporter need to send Resource attribute with each event - this is already bad (but due to good reasons to make each event self-contained), and is better to selectively send a subset of attributes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

does this comment apply to the other PR relating to traces? #3214

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I actually attempted to make the change you are suggesting for traces, but it received negative feedback so I decided not to pursue it: #3367 (comment)

Copy link
Member

Choose a reason for hiding this comment

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

does this comment apply to the other PR relating to traces? #3214

Yes.

Copy link
Member

Choose a reason for hiding this comment

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

I actually attempted to make the change you are suggesting for traces, but it received negative feedback so I decided not to pursue it: #3367 (comment)

Yes I am aware. I am asking Raj to reconsider, so as to be consistent with the prior work (OTel Rust, which has this as a stable feature already). OTel Rust did it the way it did for the reasons I shared in earlier comment.


foreach (var entry in this.propertiesEntries)
{
// A prepopulated env_properties entry should not be added if the same key exists in the log,
Copy link
Member

Choose a reason for hiding this comment

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

GenevaExporter previously did not attempt de-duplication for performance reasons (neither did upstream OTel sdk). I don't think we need to do it now either as this will affect perf.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it was previously not possible to have a duplicate in env_properties. Do you think I should remove this check for duplicates between resource attributes and log fields? How do I weigh sending bad data to the agents versus performance impact?

Copy link
Member

Choose a reason for hiding this comment

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

For Logs, duplicates were possible before. (eg: #736).

The current behavior is to let Agent deal with the duplicate data. It may/may-not be ideal, but that is the current state. (IIRC, metrics also don't do de-duplication of attributes. Agent deals with de-duplication)

@Kielek Kielek changed the title implement resource attributes for geneva logs [Exporter.Geneva] implement resource attributes for logs Nov 21, 2025
private readonly Dictionary<string, object> prepopulatedFields;

// These are values that are always added to env_properties
private readonly Dictionary<string, object> propertiesEntries;
Copy link
Member

Choose a reason for hiding this comment

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

FrozenDictionary is optimized for read-heavy scenarios with zero-allocation lookups and perfect hashing. Switching to regular Dictionary adds a lookup overhead

var idxMapSizePatch = cursor - 2;

if (this.prepopulatedFieldKeys != null)
this.AddResourceAttributesToPrepopulated();
Copy link
Member

Choose a reason for hiding this comment

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

This method runs on every log record, which is concerning for the hot path. While the idempotency guards prevent duplicate additions, we're still invoking the resourceProvider delegate, iterating all resource attributes, and performing dictionary lookups per-record. Additionally, the .Any() calls allocate an enumerator and closure on each invocation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:exporter.geneva Things related to OpenTelemetry.Exporter.Geneva perf Performance related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants