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

Commit

Permalink
make logger immutable (#1783)
Browse files Browse the repository at this point in the history
Co-authored-by: stas <statis@microsoft.com>
  • Loading branch information
2 people authored and AdamL-Microsoft committed Apr 18, 2022
1 parent 3372105 commit 29f279c
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 52 deletions.
135 changes: 93 additions & 42 deletions src/ApiService/ApiService/Log.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ namespace Microsoft.OneFuzz.Service;

public interface ILog
{
void Log(Guid correlationId, String message, SeverityLevel level, IDictionary<string, string> tags, string? caller);
void LogEvent(Guid correlationId, String evt, IDictionary<string, string> tags, IDictionary<string, double>? metrics, string? caller);
void LogException(Guid correlationId, Exception ex, IDictionary<string, string> tags, IDictionary<string, double>? metrics, string? caller);
void Log(Guid correlationId, String message, SeverityLevel level, IReadOnlyDictionary<string, string> tags, string? caller);
void LogEvent(Guid correlationId, String evt, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller);
void LogException(Guid correlationId, Exception ex, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller);
void Flush();
}

Expand All @@ -22,24 +22,39 @@ class AppInsights : ILog
new TelemetryClient(
new TelemetryConfiguration(EnvironmentVariables.AppInsights.InstrumentationKey));

public void Log(Guid correlationId, String message, SeverityLevel level, IDictionary<string, string> tags, string? caller)
public void Log(Guid correlationId, String message, SeverityLevel level, IReadOnlyDictionary<string, string> tags, string? caller)
{
tags["Correlation ID"] = correlationId.ToString();
if (caller is not null) tags["CalledBy"] = caller;
telemetryClient.TrackTrace(message, level, tags);
Dictionary<string, string> copyTags = new(tags);
copyTags["Correlation ID"] = correlationId.ToString();
if (caller is not null) copyTags["CalledBy"] = caller;
telemetryClient.TrackTrace(message, level, copyTags);
}
public void LogEvent(Guid correlationId, String evt, IDictionary<string, string> tags, IDictionary<string, double>? metrics, string? caller)
public void LogEvent(Guid correlationId, String evt, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller)
{
tags["Correlation ID"] = correlationId.ToString();
if (caller is not null) tags["CalledBy"] = caller;
telemetryClient.TrackEvent(evt, properties: tags, metrics: metrics);
Dictionary<string, string> copyTags = new(tags);
copyTags["Correlation ID"] = correlationId.ToString();
if (caller is not null) copyTags["CalledBy"] = caller;

Dictionary<string, double>? copyMetrics = null;
if (metrics is not null)
{
copyMetrics = new(metrics);
}

telemetryClient.TrackEvent(evt, properties: copyTags, metrics: copyMetrics);
}
public void LogException(Guid correlationId, Exception ex, IDictionary<string, string> tags, IDictionary<string, double>? metrics, string? caller)
public void LogException(Guid correlationId, Exception ex, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller)
{
tags["Correlation ID"] = correlationId.ToString();
Dictionary<string, string> copyTags = new(tags);
copyTags["Correlation ID"] = correlationId.ToString();
if (caller is not null) copyTags["CalledBy"] = caller;

if (caller is not null) tags["CalledBy"] = caller;
telemetryClient.TrackException(ex, tags, metrics);
Dictionary<string, double>? copyMetrics = null;
if (metrics is not null)
{
copyMetrics = new(metrics);
}
telemetryClient.TrackException(ex, copyTags, copyMetrics);
}

public void Flush()
Expand All @@ -52,7 +67,7 @@ public void Flush()
class Console : ILog
{

private string DictToString<T>(IDictionary<string, T>? d)
private string DictToString<T>(IReadOnlyDictionary<string, T>? d)
{
if (d is null)
{
Expand All @@ -64,41 +79,41 @@ private string DictToString<T>(IDictionary<string, T>? d)
}
}

private void LogTags(Guid correlationId, string? caller, IDictionary<string, string> tags)
private void LogTags(Guid correlationId, IReadOnlyDictionary<string, string> tags)
{
var ts = DictToString(tags);
if (!string.IsNullOrEmpty(ts))
{
System.Console.WriteLine($"[{correlationId}:{caller}] Tags:{ts}");
System.Console.WriteLine($"[{correlationId}] Tags:{ts}");
}
}

private void LogMetrics(Guid correlationId, string? caller, IDictionary<string, double>? metrics)
private void LogMetrics(Guid correlationId, IReadOnlyDictionary<string, double>? metrics)
{
var ms = DictToString(metrics);
if (!string.IsNullOrEmpty(ms))
{
System.Console.Out.WriteLine($"[{correlationId}:{caller}] Metrics:{DictToString(metrics)}");
System.Console.Out.WriteLine($"[{correlationId}] Metrics:{DictToString(metrics)}");
}
}

public void Log(Guid correlationId, String message, SeverityLevel level, IDictionary<string, string> tags, string? caller)
public void Log(Guid correlationId, String message, SeverityLevel level, IReadOnlyDictionary<string, string> tags, string? caller)
{
System.Console.Out.WriteLine($"[{correlationId}:{caller}][{level}] {message}");
LogTags(correlationId, caller, tags);
System.Console.Out.WriteLine($"[{correlationId}][{level}] {message}");
LogTags(correlationId, tags);
}

public void LogEvent(Guid correlationId, String evt, IDictionary<string, string> tags, IDictionary<string, double>? metrics, string? caller)
public void LogEvent(Guid correlationId, String evt, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller)
{
System.Console.Out.WriteLine($"[{correlationId}:{caller}][Event] {evt}");
LogTags(correlationId, caller, tags);
LogMetrics(correlationId, caller, metrics);
System.Console.Out.WriteLine($"[{correlationId}][Event] {evt}");
LogTags(correlationId, tags);
LogMetrics(correlationId, metrics);
}
public void LogException(Guid correlationId, Exception ex, IDictionary<string, string> tags, IDictionary<string, double>? metrics, string? caller)
public void LogException(Guid correlationId, Exception ex, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller)
{
System.Console.Out.WriteLine($"[{correlationId}:{caller}][Exception] {ex}");
LogTags(correlationId, caller, tags);
LogMetrics(correlationId, caller, metrics);
System.Console.Out.WriteLine($"[{correlationId}][Exception] {ex}");
LogTags(correlationId, tags);
LogMetrics(correlationId, metrics);
}
public void Flush()
{
Expand All @@ -108,15 +123,17 @@ public void Flush()

public interface ILogTracer
{
IDictionary<string, string> Tags { get; }
IReadOnlyDictionary<string, string> Tags { get; }

void Critical(string message);
void Error(string message);
void Event(string evt, IDictionary<string, double>? metrics);
void Exception(Exception ex, IDictionary<string, double>? metrics);
void Event(string evt, IReadOnlyDictionary<string, double>? metrics);
void Exception(Exception ex, IReadOnlyDictionary<string, double>? metrics);
void ForceFlush();
void Info(string message);
void Warning(string message);

ILogTracer AddTags((string, string)[]? tags);
}

public class LogTracer : ILogTracer
Expand All @@ -129,15 +146,49 @@ public class LogTracer : ILogTracer
private List<ILog> _loggers;

public Guid CorrelationId { get; }
public IDictionary<string, string> Tags { get; }
public IReadOnlyDictionary<string, string> Tags { get; }


public LogTracer(Guid correlationId, List<ILog> loggers)
private static List<KeyValuePair<string, string>> ConvertTags((string, string)[]? tags)
{
List<KeyValuePair<string, string>> converted = new List<KeyValuePair<string, string>>();
if (tags is null)
{
return converted;
}
else
{
foreach (var (k, v) in tags)
{
converted.Add(new KeyValuePair<string, string>(k, v));
}
return converted;
}
}

public LogTracer(Guid correlationId, (string, string)[]? tags, List<ILog> loggers) : this(correlationId, new Dictionary<string, string>(ConvertTags(tags)), loggers) { }


public LogTracer(Guid correlationId, IReadOnlyDictionary<string, string> tags, List<ILog> loggers)
{
CorrelationId = correlationId;
Tags = new Dictionary<string, string>();
Tags = tags;
_loggers = loggers;
}

public ILogTracer AddTags((string, string)[]? tags)
{
var newTags = new Dictionary<string, string>(Tags);
if (tags is not null)
{
foreach (var (k, v) in tags)
{
newTags[k] = v;
}
}
return new LogTracer(CorrelationId, newTags, _loggers);
}

public void Info(string message)
{
var caller = GetCaller();
Expand Down Expand Up @@ -174,7 +225,7 @@ public void Critical(string message)
}
}

public void Event(string evt, IDictionary<string, double>? metrics)
public void Event(string evt, IReadOnlyDictionary<string, double>? metrics)
{
var caller = GetCaller();
foreach (var logger in _loggers)
Expand All @@ -183,7 +234,7 @@ public void Event(string evt, IDictionary<string, double>? metrics)
}
}

public void Exception(Exception ex, IDictionary<string, double>? metrics)
public void Exception(Exception ex, IReadOnlyDictionary<string, double>? metrics)
{
var caller = GetCaller();
foreach (var logger in _loggers)
Expand All @@ -203,7 +254,7 @@ public void ForceFlush()

public interface ILogTracerFactory
{
LogTracer MakeLogTracer(Guid correlationId);
LogTracer MakeLogTracer(Guid correlationId, (string, string)[]? tags = null);
}

public class LogTracerFactory : ILogTracerFactory
Expand All @@ -215,9 +266,9 @@ public LogTracerFactory(List<ILog> loggers)
_loggers = loggers;
}

public LogTracer MakeLogTracer(Guid correlationId)
public LogTracer MakeLogTracer(Guid correlationId, (string, string)[]? tags = null)
{
return new(correlationId, _loggers);
return new(correlationId, tags, _loggers);
}

}
5 changes: 1 addition & 4 deletions src/ApiService/ApiService/QueueProxyHeartbeat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,11 @@ public async Task Run([QueueTrigger("myqueue-items", Connection = "AzureWebJobsS
var hb = JsonSerializer.Deserialize<ProxyHeartbeat>(msg, EntityConverter.GetJsonSerializerOptions()).EnsureNotNull($"wrong data {msg}"); ;
var newHb = hb with { TimeStamp = DateTimeOffset.UtcNow };

log.Tags["Proxy ID"] = newHb.ProxyId.ToString();


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

if (proxy == null)
{
log.Warning($"invalid proxy id: {newHb.ProxyId}");
log.AddTags(new[] { ("Proxy ID", newHb.ProxyId.ToString()) }).Warning($"invalid proxy id: {newHb.ProxyId}");
return;
}
var newProxy = proxy with { heartbeat = newHb };
Expand Down
4 changes: 1 addition & 3 deletions src/ApiService/ApiService/onefuzzlib/Events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,11 @@ public void LogEvent(ILogTracer log, BaseEvent anEvent, EventType eventType)
options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
options.Converters.Add(new RemoveUserInfo());
var serializedEvent = JsonSerializer.Serialize(anEvent, options);
log.Tags["Event Type"] = eventType.ToString();
log.Info($"sending event: {eventType} - {serializedEvent}");
log.AddTags(new[] { ("Event Type", eventType.ToString()) }).Info($"sending event: {eventType} - {serializedEvent}");
}
}



internal class RemoveUserInfo : JsonConverter<UserInfo>
{
public override UserInfo? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
Expand Down
9 changes: 6 additions & 3 deletions src/ApiService/ApiService/onefuzzlib/WebhookOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,12 @@ public async Task QueueWebhook(WebhookMessageLog webhookLog)

if (visibilityTimeout == null)
{
log.Tags["WebhookId"] = webhookLog.WebhookId.ToString();
log.Tags["EventId"] = webhookLog.EventId.ToString();
log.Error($"invalid WebhookMessage queue state, not queuing. {webhookLog.WebhookId}:{webhookLog.EventId} - {webhookLog.State}");
log.AddTags(
new[] {
("WebhookId", webhookLog.WebhookId.ToString()),
("EventId", webhookLog.EventId.ToString()) }
).
Error($"invalid WebhookMessage queue state, not queuing. {webhookLog.WebhookId}:{webhookLog.EventId} - {webhookLog.State}");
}
else
{
Expand Down

0 comments on commit 29f279c

Please sign in to comment.