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

Commit ccd9717

Browse files
author
stas
committed
make logger immutable
1 parent 9fc80b9 commit ccd9717

File tree

4 files changed

+89
-42
lines changed

4 files changed

+89
-42
lines changed

src/ApiService/ApiService/Log.cs

Lines changed: 81 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ namespace Microsoft.OneFuzz.Service;
1010

1111
public interface ILog
1212
{
13-
void Log(Guid correlationId, String message, SeverityLevel level, IDictionary<string, string> tags, string? caller);
14-
void LogEvent(Guid correlationId, String evt, IDictionary<string, string> tags, IDictionary<string, double>? metrics, string? caller);
15-
void LogException(Guid correlationId, Exception ex, IDictionary<string, string> tags, IDictionary<string, double>? metrics, string? caller);
13+
void Log(Guid correlationId, String message, SeverityLevel level, IReadOnlyDictionary<string, string> tags, string? caller);
14+
void LogEvent(Guid correlationId, String evt, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller);
15+
void LogException(Guid correlationId, Exception ex, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller);
1616
void Flush();
1717
}
1818

@@ -22,24 +22,38 @@ class AppInsights : ILog
2222
new TelemetryClient(
2323
new TelemetryConfiguration(EnvironmentVariables.AppInsights.InstrumentationKey));
2424

25-
public void Log(Guid correlationId, String message, SeverityLevel level, IDictionary<string, string> tags, string? caller)
25+
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
}
31-
public void LogEvent(Guid correlationId, String evt, IDictionary<string, string> tags, IDictionary<string, double>? metrics, string? caller)
32+
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 Dictionary<string, string>(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+
copyMetrics = new(metrics);
41+
}
42+
43+
telemetryClient.TrackEvent(evt, properties: copyTags, metrics: copyMetrics);
3644
}
37-
public void LogException(Guid correlationId, Exception ex, IDictionary<string, string> tags, IDictionary<string, double>? metrics, string? caller)
45+
public void LogException(Guid correlationId, Exception ex, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller)
3846
{
39-
tags["Correlation ID"] = correlationId.ToString();
47+
Dictionary<string, string> copyTags = new Dictionary<string, string>(tags);
48+
copyTags["Correlation ID"] = correlationId.ToString();
49+
if (caller is not null) copyTags["CalledBy"] = caller;
4050

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

4559
public void Flush()
@@ -52,7 +66,7 @@ public void Flush()
5266
class Console : ILog
5367
{
5468

55-
private string DictToString<T>(IDictionary<string, T>? d)
69+
private string DictToString<T>(IReadOnlyDictionary<string, T>? d)
5670
{
5771
if (d is null)
5872
{
@@ -64,7 +78,7 @@ private string DictToString<T>(IDictionary<string, T>? d)
6478
}
6579
}
6680

67-
private void LogTags(Guid correlationId, string? caller, IDictionary<string, string> tags)
81+
private void LogTags(Guid correlationId, string? caller, IReadOnlyDictionary<string, string> tags)
6882
{
6983
var ts = DictToString(tags);
7084
if (!string.IsNullOrEmpty(ts))
@@ -73,7 +87,7 @@ private void LogTags(Guid correlationId, string? caller, IDictionary<string, str
7387
}
7488
}
7589

76-
private void LogMetrics(Guid correlationId, string? caller, IDictionary<string, double>? metrics)
90+
private void LogMetrics(Guid correlationId, string? caller, IReadOnlyDictionary<string, double>? metrics)
7791
{
7892
var ms = DictToString(metrics);
7993
if (!string.IsNullOrEmpty(ms))
@@ -82,19 +96,19 @@ private void LogMetrics(Guid correlationId, string? caller, IDictionary<string,
8296
}
8397
}
8498

85-
public void Log(Guid correlationId, String message, SeverityLevel level, IDictionary<string, string> tags, string? caller)
99+
public void Log(Guid correlationId, String message, SeverityLevel level, IReadOnlyDictionary<string, string> tags, string? caller)
86100
{
87101
System.Console.Out.WriteLine($"[{correlationId}:{caller}][{level}] {message}");
88102
LogTags(correlationId, caller, tags);
89103
}
90104

91-
public void LogEvent(Guid correlationId, String evt, IDictionary<string, string> tags, IDictionary<string, double>? metrics, string? caller)
105+
public void LogEvent(Guid correlationId, String evt, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller)
92106
{
93107
System.Console.Out.WriteLine($"[{correlationId}:{caller}][Event] {evt}");
94108
LogTags(correlationId, caller, tags);
95109
LogMetrics(correlationId, caller, metrics);
96110
}
97-
public void LogException(Guid correlationId, Exception ex, IDictionary<string, string> tags, IDictionary<string, double>? metrics, string? caller)
111+
public void LogException(Guid correlationId, Exception ex, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller)
98112
{
99113
System.Console.Out.WriteLine($"[{correlationId}:{caller}][Exception] {ex}");
100114
LogTags(correlationId, caller, tags);
@@ -108,15 +122,17 @@ public void Flush()
108122

109123
public interface ILogTracer
110124
{
111-
IDictionary<string, string> Tags { get; }
125+
IReadOnlyDictionary<string, string> Tags { get; }
112126

113127
void Critical(string message);
114128
void Error(string message);
115-
void Event(string evt, IDictionary<string, double>? metrics);
116-
void Exception(Exception ex, IDictionary<string, double>? metrics);
129+
void Event(string evt, IReadOnlyDictionary<string, double>? metrics);
130+
void Exception(Exception ex, IReadOnlyDictionary<string, double>? metrics);
117131
void ForceFlush();
118132
void Info(string message);
119133
void Warning(string message);
134+
135+
ILogTracer AddTags((string, string)[]? tags);
120136
}
121137

122138
public class LogTracer : ILogTracer
@@ -129,15 +145,47 @@ public class LogTracer : ILogTracer
129145
private List<ILog> _loggers;
130146

131147
public Guid CorrelationId { get; }
132-
public IDictionary<string, string> Tags { get; }
148+
public IReadOnlyDictionary<string, string> Tags { get; }
133149

134-
public LogTracer(Guid correlationId, List<ILog> loggers)
135-
{
150+
151+
private static List<KeyValuePair<string, string>> ConvertTags((string, string)[]? tags) {
152+
List<KeyValuePair<string, string>> converted = new List<KeyValuePair<string, string>>();
153+
if (tags is null)
154+
{
155+
return converted;
156+
}
157+
else
158+
{
159+
foreach (var (k, v) in tags) {
160+
converted.Add(new KeyValuePair<string, string>(k, v));
161+
}
162+
return converted;
163+
}
164+
}
165+
166+
public LogTracer(Guid correlationId, (string, string)[]? tags, List<ILog> loggers) : this(correlationId, new Dictionary<string, string>(ConvertTags(tags)), loggers) { }
167+
168+
169+
public LogTracer(Guid correlationId, IReadOnlyDictionary<string, string> tags, List<ILog> loggers) {
136170
CorrelationId = correlationId;
137-
Tags = new Dictionary<string, string>();
171+
Tags = tags;
138172
_loggers = loggers;
139173
}
140174

175+
public ILogTracer AddTags((string, string)[]? tags) {
176+
177+
var newTags = new Dictionary<string, string>(Tags);
178+
if (tags is not null)
179+
{
180+
foreach (var (k, v) in tags)
181+
{
182+
newTags[k] = v;
183+
}
184+
}
185+
return new LogTracer(CorrelationId, newTags, _loggers);
186+
}
187+
188+
141189
public void Info(string message)
142190
{
143191
var caller = GetCaller();
@@ -174,7 +222,7 @@ public void Critical(string message)
174222
}
175223
}
176224

177-
public void Event(string evt, IDictionary<string, double>? metrics)
225+
public void Event(string evt, IReadOnlyDictionary<string, double>? metrics)
178226
{
179227
var caller = GetCaller();
180228
foreach (var logger in _loggers)
@@ -183,7 +231,7 @@ public void Event(string evt, IDictionary<string, double>? metrics)
183231
}
184232
}
185233

186-
public void Exception(Exception ex, IDictionary<string, double>? metrics)
234+
public void Exception(Exception ex, IReadOnlyDictionary<string, double>? metrics)
187235
{
188236
var caller = GetCaller();
189237
foreach (var logger in _loggers)
@@ -203,7 +251,7 @@ public void ForceFlush()
203251

204252
public interface ILogTracerFactory
205253
{
206-
LogTracer MakeLogTracer(Guid correlationId);
254+
LogTracer MakeLogTracer(Guid correlationId, (string, string)[]? tags = null);
207255
}
208256

209257
public class LogTracerFactory : ILogTracerFactory
@@ -215,9 +263,9 @@ public LogTracerFactory(List<ILog> loggers)
215263
_loggers = loggers;
216264
}
217265

218-
public LogTracer MakeLogTracer(Guid correlationId)
266+
public LogTracer MakeLogTracer(Guid correlationId, (string, string)[]? tags = null)
219267
{
220-
return new(correlationId, _loggers);
268+
return new(correlationId, tags, _loggers);
221269
}
222270

223271
}

src/ApiService/ApiService/QueueProxyHeartbeat.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,13 @@ 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-
31+
var log2 = log.AddTags(new[] { ("Proxy ID", newHb.ProxyId.ToString())});
3332

3433
var proxy = await _proxy.GetByProxyId(newHb.ProxyId);
3534

3635
if (proxy == null)
3736
{
38-
log.Warning($"invalid proxy id: {newHb.ProxyId}");
37+
log2.Warning($"invalid proxy id: {newHb.ProxyId}");
3938
return;
4039
}
4140
var newProxy = proxy with { heartbeat = newHb };

src/ApiService/ApiService/onefuzzlib/Events.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using ApiService.OneFuzzLib;
2+
using Microsoft.Graph;
23
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;
34
using System;
45
using System.Collections.Generic;
@@ -68,13 +69,13 @@ public void LogEvent(ILogTracer log, BaseEvent anEvent, EventType eventType)
6869
options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
6970
options.Converters.Add(new RemoveUserInfo());
7071
var serializedEvent = JsonSerializer.Serialize(anEvent, options);
71-
log.Tags["Event Type"] = eventType.ToString();
72-
log.Info($"sending event: {eventType} - {serializedEvent}");
72+
73+
var log2 = log.AddTags(new[] {("Event Type", eventType.ToString()) });
74+
log2.Info($"sending event: {eventType} - {serializedEvent}");
7375
}
7476
}
7577

7678

77-
7879
internal class RemoveUserInfo : JsonConverter<UserInfo>
7980
{
8081
public override UserInfo? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)

src/ApiService/ApiService/onefuzzlib/WebhookOperations.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ public async Task QueueWebhook(WebhookMessageLog webhookLog)
4343

4444
if (visibilityTimeout == null)
4545
{
46-
log.Tags["WebhookId"] = webhookLog.WebhookId.ToString();
47-
log.Tags["EventId"] = webhookLog.EventId.ToString();
48-
log.Error($"invalid WebhookMessage queue state, not queuing. {webhookLog.WebhookId}:{webhookLog.EventId} - {webhookLog.State}");
46+
var log2 = log.AddTags(new []{("WebhookId", webhookLog.WebhookId.ToString()), ("EventId", webhookLog.EventId.ToString())});
47+
log2.Error($"invalid WebhookMessage queue state, not queuing. {webhookLog.WebhookId}:{webhookLog.EventId} - {webhookLog.State}");
4948
}
5049
else
5150
{

0 commit comments

Comments
 (0)