Multi Targeting
Multi-Target Telemetry Generation
Section titled “Multi-Target Telemetry Generation”Multi-targeting allows you to generate multiple types of telemetry (Activities, Logs, and Metrics) from a single interface or even a single method.
Interface-Level Multi-Targeting
Section titled “Interface-Level Multi-Targeting”Apply multiple generation attributes to an interface to enable all telemetry types:
using Purview.Telemetry;
[ActivitySource("OrderService")][Logger][Meter("OrderService")]interface IOrderTelemetry{ // Methods can use one or more telemetry types}Method-Level Multi-Targeting
Section titled “Method-Level Multi-Targeting”Multiple Targets on One Method
Section titled “Multiple Targets on One Method”v4 supports combining multiple telemetry attributes on a single method. When called, the method emits all specified telemetry types simultaneously:
[ActivitySource("OrderService")][Logger][Meter]interface IOrderTelemetry{ // MULTI-TARGET: Creates Activity + Logs Info + Increments Counter - all from one call! [Activity] [Info] [AutoCounter] Activity? ProcessingOrder([Baggage]int orderId, [Tag]string customerName);
// MULTI-TARGET: Adds ActivityEvent + Logs as Debug [Event] [Debug] void OrderValidated(Activity? activity, decimal amount);
// SINGLE-TARGET: Only logs [Warning] void OrderRejected(int orderId, string reason);
// SINGLE-TARGET: Only metric [Histogram] void OrderProcessingDuration([InstrumentMeasurement]int milliseconds);}Usage:
// Single method call emits 3 telemetry types!using var activity = telemetry.ProcessingOrder(123, "Acme Corp");// ✓ Activity created and started// ✓ Info log entry written// ✓ Counter incremented by 1Supported Multi-Target Combinations
Section titled “Supported Multi-Target Combinations”| Combination | Supported | Example |
|---|---|---|
| Activity + Log | ✅ Yes | [Activity] + [Info] |
| Activity + Metric | ✅ Yes | [Activity] + [AutoCounter] |
| Log + Metric | ✅ Yes | [Info] + [Histogram] |
| Activity + Log + Metric | ✅ Yes | [Activity] + [Info] + [AutoCounter] |
| Event + Log | ✅ Yes | [Event] + [Debug] |
| Context + Log | ✅ Yes | [Context] + [Trace] |
Important Rules:
- Only one attribute per telemetry family is allowed per method
- Activities: Use ONE of
[Activity],[Event], or[Context] - Logging: Use ONE of
[Log],[Trace],[Debug],[Info],[Warning],[Error],[Critical] - Metrics: Use ONE of
[Counter],[AutoCounter],[Histogram],[UpDownCounter], or Observable variants
Invalid Examples:
// ERROR TSG1002: Multiple activity attributes[Activity][Event]void InvalidMethod(Activity? activity);
// ERROR TSG1002: Multiple logging attributes[Info][Warning]void InvalidMethod(string message);
// ERROR TSG1002: Multiple metric attributes[Counter][Histogram]void InvalidMethod([InstrumentMeasurement]int value);Excluding Parameters from Specific Targets
Section titled “Excluding Parameters from Specific Targets”When using multi-target methods, you may want certain parameters to only apply to specific telemetry types. Use [ExcludeTargets] to control this:
using Purview.Telemetry;
[ActivitySource("PaymentService")][Logger][Meter]interface IPaymentTelemetry{ [Activity] [Info] [Counter] Activity? ProcessingPayment( [Baggage]Guid paymentId,
// Exclude verbose message from metrics (would be wasted as tag) [ExcludeTargets(Targets.Metrics)] string processingMessage,
// Measurement only applies to metrics [InstrumentMeasurement] decimal amount,
// Exclude internal details from Activity baggage [ExcludeTargets(Targets.Activities)] [Tag] // Still included in logs and metrics string internalReference );}ExcludeTargets Values
Section titled “ExcludeTargets Values”[Flags]public enum Targets{ Activities = 1, Logging = 2, Metrics = 4}Usage:
// Exclude from multiple targets[ExcludeTargets(Targets.Activities | Targets.Metrics)]string loggingOnlyParameter
// Exclude from single target[ExcludeTargets(Targets.Logging)]int metricsAndActivityParameterInference Rules with Multi-Targeting
Section titled “Inference Rules with Multi-Targeting”⚠️ Important: Inference is Disabled
Section titled “⚠️ Important: Inference is Disabled”When an interface has multiple class-level attributes ([ActivitySource], [Logger], [Meter]), inference is disabled. You must explicitly specify generation targets on each method.
[ActivitySource("MyApp")][Logger][Meter]interface IMyTelemetry{ // ERROR TSG1001: No explicit attribute void ProcessItem(int id);
// ✅ CORRECT: Explicit attribute [Info] void ProcessItem(int id);
// ✅ CORRECT: Excluded from generation [Exclude] void ProcessItem(int id);}Single-Target Interfaces Support Inference
Section titled “Single-Target Interfaces Support Inference”If your interface has only ONE generation attribute, inference works normally:
// Single-target: Inference enabled[Logger]interface ILogOnlyTelemetry{ // ✅ Inferred as [Info] because of Exception void ProcessItem(int id, Exception ex);
// ✅ Inferred as scoped log (returns IDisposable) IDisposable? ProcessingBatch(int batchId);}Return Types with Multi-Targeting
Section titled “Return Types with Multi-Targeting”Activity + Other Targets
Section titled “Activity + Other Targets”When combining [Activity] with logs/metrics, return Activity?:
[Activity][Info][AutoCounter]Activity? ProcessingOrder(int orderId); // ✅ Returns ActivityLog + Metric (No Activity)
Section titled “Log + Metric (No Activity)”When combining logs and metrics without activities, return void or IDisposable?:
[Info][Histogram]void RecordOperation([InstrumentMeasurement]int duration, string operation); // ✅ void
[Info][AutoCounter]IDisposable? ProcessingBatch(int batchId); // ✅ Scoped log + counterEvent/Context + Log
Section titled “Event/Context + Log”Events and Context methods with logs should return void:
[Event][Debug]void OrderCompleted(Activity? activity, decimal total); // ✅ voidCommon Multi-Targeting Patterns
Section titled “Common Multi-Targeting Patterns”Pattern 1: Complete Observability Method
Section titled “Pattern 1: Complete Observability Method”Track everything about an operation:
[Activity] // Distributed tracing[Info] // Structured logging[AutoCounter] // Count occurrencesActivity? ProcessingRequest( [Baggage]string requestId, [Tag]string endpoint, [Tag]string method);Pattern 2: Event with Context Logging
Section titled “Pattern 2: Event with Context Logging”Add activity events and log them:
[Event][Debug]void StepCompleted( Activity? activity, [Tag]string stepName, [Tag]int duration);Pattern 3: Logging with Metrics
Section titled “Pattern 3: Logging with Metrics”Log operations and track distributions:
[Info][Histogram]void RequestCompleted( [InstrumentMeasurement]int durationMs, [Tag]string endpoint, [Tag]int statusCode);Pattern 4: Selective Parameter Usage
Section titled “Pattern 4: Selective Parameter Usage”Use different parameters for different telemetry:
[Activity][Info][Counter]Activity? ApiCall( [Baggage]string traceId, // Activity baggage only
[ExcludeTargets(Targets.Metrics)] string verboseMessage, // Activity + Log only
[InstrumentMeasurement] [ExcludeTargets(Targets.Activities | Targets.Logging)] int callCount, // Metrics only
[Tag]string endpoint // All three!);Benefits of Multi-Targeting
Section titled “Benefits of Multi-Targeting”- Less Code - One method definition generates multiple telemetry types
- Consistency - Same parameters used across telemetry types (when appropriate)
- Atomicity - All telemetry emitted together, no risk of forgetting one
- Maintainability - Change once, affects all telemetry types
- Performance - Single method call overhead instead of multiple
Diagnostics
Section titled “Diagnostics”| Diagnostic | When | Resolution |
|---|---|---|
TSG1001 |
Method has no explicit attribute in multi-target interface | Add [Activity], [Info], [Counter], etc., or [Exclude] |
TSG1002 |
Multiple attributes from same family | Use only one Activity, Logging, or Metrics attribute per method |
TSG1006 |
[ExcludeTargets] references missing target |
Remove [ExcludeTargets] or add the target attribute to the method |
TSG1007 |
[ExcludeTargets] results in invalid config |
Adjust exclusions to ensure valid parameters remain for each target |
See Also
Section titled “See Also”- Activities - Activity generation details
- Logging - Logging generation details
- Metrics - Metrics generation details
- Getting Started - Multi-target examples
- Diagnostics - Error codes and resolutions