mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-17 12:28:07 +00:00
make logger immutable (#1783)
Co-authored-by: stas <statis@microsoft.com>
This commit is contained in:
@ -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();
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
public void LogException(Guid correlationId, Exception ex, IDictionary<string, string> tags, IDictionary<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.TrackEvent(evt, properties: copyTags, metrics: copyMetrics);
|
||||
}
|
||||
public void LogException(Guid correlationId, Exception ex, IReadOnlyDictionary<string, string> tags, IReadOnlyDictionary<string, double>? metrics, string? caller)
|
||||
{
|
||||
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.TrackException(ex, copyTags, copyMetrics);
|
||||
}
|
||||
|
||||
public void Flush()
|
||||
@ -52,7 +67,7 @@ class AppInsights : ILog
|
||||
class Console : ILog
|
||||
{
|
||||
|
||||
private string DictToString<T>(IDictionary<string, T>? d)
|
||||
private string DictToString<T>(IReadOnlyDictionary<string, T>? d)
|
||||
{
|
||||
if (d is null)
|
||||
{
|
||||
@ -64,41 +79,41 @@ class Console : ILog
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
@ -108,15 +123,17 @@ class Console : ILog
|
||||
|
||||
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
|
||||
@ -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();
|
||||
@ -174,7 +225,7 @@ public class LogTracer : ILogTracer
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@ -183,7 +234,7 @@ public class LogTracer : ILogTracer
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@ -203,7 +254,7 @@ public class LogTracer : ILogTracer
|
||||
|
||||
public interface ILogTracerFactory
|
||||
{
|
||||
LogTracer MakeLogTracer(Guid correlationId);
|
||||
LogTracer MakeLogTracer(Guid correlationId, (string, string)[]? tags = null);
|
||||
}
|
||||
|
||||
public class LogTracerFactory : ILogTracerFactory
|
||||
@ -215,9 +266,9 @@ public class LogTracerFactory : ILogTracerFactory
|
||||
_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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,14 +28,11 @@ public class QueueProxyHearbeat
|
||||
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 };
|
||||
|
@ -68,13 +68,11 @@ namespace Microsoft.OneFuzz.Service
|
||||
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)
|
||||
|
@ -43,9 +43,12 @@ public class WebhookMessageLogOperations : Orm<WebhookMessageLog>, IWebhookMessa
|
||||
|
||||
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
|
||||
{
|
||||
|
Reference in New Issue
Block a user