Skip to content
This repository was archived by the owner on Nov 1, 2023. It is now read-only.

Commit 6235e5d

Browse files
stishkinstas
authored andcommitted
make logger immutable (#1783)
Co-authored-by: stas <statis@microsoft.com>
1 parent 3efd04d commit 6235e5d

File tree

4 files changed

+84
-40
lines changed

4 files changed

+84
-40
lines changed

src/ApiService/ApiService/Log.cs

Lines changed: 76 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,37 @@ class AppInsights : ILog
2424

2525
public void Log(Guid correlationId, String message, SeverityLevel level, IReadOnlyDictionary<string, string> tags, string? caller)
2626
{
27-
tags["Correlation ID"] = correlationId.ToString();
28-
if (caller is not null) tags["CalledBy"] = caller;
29-
telemetryClient.TrackTrace(message, level, tags);
27+
Dictionary<string, string> copyTags = new(tags);
28+
copyTags["Correlation ID"] = correlationId.ToString();
29+
if (caller is not null) copyTags["CalledBy"] = caller;
30+
telemetryClient.TrackTrace(message, level, copyTags);
3031
}
3132
public void LogEvent(Guid correlationId, String evt, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller)
3233
{
33-
tags["Correlation ID"] = correlationId.ToString();
34-
if (caller is not null) tags["CalledBy"] = caller;
35-
telemetryClient.TrackEvent(evt, properties: tags, metrics: metrics);
34+
Dictionary<string, string> copyTags = new(tags);
35+
copyTags["Correlation ID"] = correlationId.ToString();
36+
if (caller is not null) copyTags["CalledBy"] = caller;
37+
38+
Dictionary<string, double>? copyMetrics = null;
39+
if (metrics is not null)
40+
{
41+
copyMetrics = new(metrics);
42+
}
43+
44+
telemetryClient.TrackEvent(evt, properties: copyTags, metrics: copyMetrics);
3645
}
37-
public void LogException(Guid correlationId, Exception ex, IDictionary<string, string> tags, IDictionary<string, double>? metrics, string? caller)
46+
public void LogException(Guid correlationId, Exception ex, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller)
3847
{
39-
tags["Correlation ID"] = correlationId.ToString();
48+
Dictionary<string, string> copyTags = new(tags);
49+
copyTags["Correlation ID"] = correlationId.ToString();
50+
if (caller is not null) copyTags["CalledBy"] = caller;
4051

41-
if (caller is not null) tags["CalledBy"] = caller;
42-
telemetryClient.TrackException(ex, tags, metrics);
52+
Dictionary<string, double>? copyMetrics = null;
53+
if (metrics is not null)
54+
{
55+
copyMetrics = new(metrics);
56+
}
57+
telemetryClient.TrackException(ex, copyTags, copyMetrics);
4358
}
4459

4560
public void Flush()
@@ -69,7 +84,7 @@ private void LogTags(Guid correlationId, IReadOnlyDictionary<string, string> tag
6984
var ts = DictToString(tags);
7085
if (!string.IsNullOrEmpty(ts))
7186
{
72-
System.Console.WriteLine($"[{correlationId}:{caller}] Tags:{ts}");
87+
System.Console.WriteLine($"[{correlationId}] Tags:{ts}");
7388
}
7489
}
7590

@@ -78,27 +93,27 @@ private void LogMetrics(Guid correlationId, IReadOnlyDictionary<string, double>?
7893
var ms = DictToString(metrics);
7994
if (!string.IsNullOrEmpty(ms))
8095
{
81-
System.Console.Out.WriteLine($"[{correlationId}:{caller}] Metrics:{DictToString(metrics)}");
96+
System.Console.Out.WriteLine($"[{correlationId}] Metrics:{DictToString(metrics)}");
8297
}
8398
}
8499

85100
public void Log(Guid correlationId, String message, SeverityLevel level, IReadOnlyDictionary<string, string> tags, string? caller)
86101
{
87-
System.Console.Out.WriteLine($"[{correlationId}:{caller}][{level}] {message}");
88-
LogTags(correlationId, caller, tags);
102+
System.Console.Out.WriteLine($"[{correlationId}][{level}] {message}");
103+
LogTags(correlationId, tags);
89104
}
90105

91106
public void LogEvent(Guid correlationId, String evt, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller)
92107
{
93-
System.Console.Out.WriteLine($"[{correlationId}:{caller}][Event] {evt}");
94-
LogTags(correlationId, caller, tags);
95-
LogMetrics(correlationId, caller, metrics);
108+
System.Console.Out.WriteLine($"[{correlationId}][Event] {evt}");
109+
LogTags(correlationId, tags);
110+
LogMetrics(correlationId, metrics);
96111
}
97112
public void LogException(Guid correlationId, Exception ex, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller)
98113
{
99-
System.Console.Out.WriteLine($"[{correlationId}:{caller}][Exception] {ex}");
100-
LogTags(correlationId, caller, tags);
101-
LogMetrics(correlationId, caller, metrics);
114+
System.Console.Out.WriteLine($"[{correlationId}][Exception] {ex}");
115+
LogTags(correlationId, tags);
116+
LogMetrics(correlationId, metrics);
102117
}
103118
public void Flush()
104119
{
@@ -117,10 +132,8 @@ public interface ILogTracer
117132
void ForceFlush();
118133
void Info(string message);
119134
void Warning(string message);
120-
void Verbose(string message);
121135

122-
ILogTracer WithTag(string k, string v);
123-
ILogTracer WithTags((string, string)[]? tags);
136+
ILogTracer AddTags((string, string)[]? tags);
124137
}
125138

126139
internal interface ILogTracerInternal : ILogTracer
@@ -133,17 +146,49 @@ internal interface ILogTracerInternal : ILogTracer
133146
private List<ILog> _loggers;
134147

135148
public Guid CorrelationId { get; }
136-
public IDictionary<string, string> Tags { get; }
149+
public IReadOnlyDictionary<string, string> Tags { get; }
137150

138-
public class LogTracer : ILogTracerInternal
139-
{
140-
private string? GetCaller()
151+
152+
private static List<KeyValuePair<string, string>> ConvertTags((string, string)[]? tags)
153+
{
154+
List<KeyValuePair<string, string>> converted = new List<KeyValuePair<string, string>>();
155+
if (tags is null)
156+
{
157+
return converted;
158+
}
159+
else
160+
{
161+
foreach (var (k, v) in tags)
162+
{
163+
converted.Add(new KeyValuePair<string, string>(k, v));
164+
}
165+
return converted;
166+
}
167+
}
168+
169+
public LogTracer(Guid correlationId, (string, string)[]? tags, List<ILog> loggers) : this(correlationId, new Dictionary<string, string>(ConvertTags(tags)), loggers) { }
170+
171+
172+
public LogTracer(Guid correlationId, IReadOnlyDictionary<string, string> tags, List<ILog> loggers)
141173
{
142174
CorrelationId = correlationId;
143-
Tags = new Dictionary<string, string>();
175+
Tags = tags;
144176
_loggers = loggers;
145177
}
146178

179+
public ILogTracer AddTags((string, string)[]? tags)
180+
{
181+
var newTags = new Dictionary<string, string>(Tags);
182+
if (tags is not null)
183+
{
184+
foreach (var (k, v) in tags)
185+
{
186+
newTags[k] = v;
187+
}
188+
}
189+
return new LogTracer(CorrelationId, newTags, _loggers);
190+
}
191+
147192
public void Info(string message)
148193
{
149194
var caller = GetCaller();
@@ -209,7 +254,7 @@ public void ForceFlush()
209254

210255
public interface ILogTracerFactory
211256
{
212-
LogTracer CreateLogTracer(Guid correlationId, (string, string)[]? tags = null, SeverityLevel severityLevel = SeverityLevel.Verbose);
257+
LogTracer MakeLogTracer(Guid correlationId, (string, string)[]? tags = null);
213258
}
214259

215260
public class LogTracerFactory : ILogTracerFactory
@@ -221,9 +266,9 @@ public LogTracerFactory(List<ILog> loggers)
221266
_loggers = loggers;
222267
}
223268

224-
public LogTracer CreateLogTracer(Guid correlationId, (string, string)[]? tags = null, SeverityLevel severityLevel = SeverityLevel.Verbose)
269+
public LogTracer MakeLogTracer(Guid correlationId, (string, string)[]? tags = null)
225270
{
226-
return new(correlationId, _loggers);
271+
return new(correlationId, tags, _loggers);
227272
}
228273

229274
}

src/ApiService/ApiService/QueueProxyHeartbeat.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,11 @@ public async Task Run([QueueTrigger("myqueue-items", Connection = "AzureWebJobsS
2828
var hb = JsonSerializer.Deserialize<ProxyHeartbeat>(msg, EntityConverter.GetJsonSerializerOptions()).EnsureNotNull($"wrong data {msg}"); ;
2929
var newHb = hb with { TimeStamp = DateTimeOffset.UtcNow };
3030

31-
log.Tags["Proxy ID"] = newHb.ProxyId.ToString();
32-
33-
3431
var proxy = await _proxy.GetByProxyId(newHb.ProxyId);
3532

3633
if (proxy == null)
3734
{
38-
log.Warning($"invalid proxy id: {newHb.ProxyId}");
35+
log.AddTags(new[] { ("Proxy ID", newHb.ProxyId.ToString()) }).Warning($"invalid proxy id: {newHb.ProxyId}");
3936
return;
4037
}
4138
var newProxy = proxy with { heartbeat = newHb };

src/ApiService/ApiService/onefuzzlib/Events.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ public void LogEvent(ILogTracer log, BaseEvent anEvent, EventType eventType)
6868
options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
6969
options.Converters.Add(new RemoveUserInfo());
7070
var serializedEvent = JsonSerializer.Serialize(anEvent, options);
71-
log.Tags["Event Type"] = eventType.ToString();
72-
log.Info($"sending event: {eventType} - {serializedEvent}");
71+
log.AddTags(new[] { ("Event Type", eventType.ToString()) }).Info($"sending event: {eventType} - {serializedEvent}");
7372
}
7473
}
7574

src/ApiService/ApiService/onefuzzlib/WebhookOperations.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,12 @@ public async Async.Task QueueWebhook(WebhookMessageLog webhookLog)
4242

4343
if (visibilityTimeout == null)
4444
{
45-
log.Tags["WebhookId"] = webhookLog.WebhookId.ToString();
46-
log.Tags["EventId"] = webhookLog.EventId.ToString();
47-
log.Error($"invalid WebhookMessage queue state, not queuing. {webhookLog.WebhookId}:{webhookLog.EventId} - {webhookLog.State}");
45+
log.AddTags(
46+
new[] {
47+
("WebhookId", webhookLog.WebhookId.ToString()),
48+
("EventId", webhookLog.EventId.ToString()) }
49+
).
50+
Error($"invalid WebhookMessage queue state, not queuing. {webhookLog.WebhookId}:{webhookLog.EventId} - {webhookLog.State}");
4851
}
4952
else
5053
{

0 commit comments

Comments
 (0)