// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Collections.Generic; using System.Reflection; using System.Text.Json.Serialization; namespace EpicGames.Core { /// /// Different types of log values (stored in the $type field of log properties) /// public static class LogValueType { #pragma warning disable CS1591 public static readonly Utf8String Asset = new Utf8String("Asset"); public static readonly Utf8String SourceFile = new Utf8String("SourceFile"); public static readonly Utf8String Object = new Utf8String("Object"); // Arbitrary structured object public static readonly Utf8String Channel = new Utf8String("Channel"); public static readonly Utf8String Severity = new Utf8String("Severity"); public static readonly Utf8String Message = new Utf8String("Message"); public static readonly Utf8String LineNumber = new Utf8String("Line"); public static readonly Utf8String ColumnNumber = new Utf8String("Column"); public static readonly Utf8String Symbol = new Utf8String("Symbol"); public static readonly Utf8String ErrorCode = new Utf8String("ErrorCode"); public static readonly Utf8String ToolName = new Utf8String("ToolName"); public static readonly Utf8String ScreenshotTest = new Utf8String("ScreenshotTest"); public static readonly Utf8String DepotPath = new Utf8String("DepotPath"); public static readonly Utf8String Link = new Utf8String("Link"); #pragma warning restore CS1591 } /// /// Attribute indicating that a type should be tagged in log output /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] public sealed class LogValueTypeAttribute : Attribute { /// /// Name to use for the type tag /// public string? Name { get; } /// /// Constructor /// public LogValueTypeAttribute(string? name = null) => Name = name; } /// /// Information for a structured value for use in log events /// public sealed class LogValue { /// /// Type of the event /// public Utf8String Type { get; set; } /// /// Rendering of the value /// public string Text { get; set; } /// /// Properties associated with the value /// public Dictionary? Properties { get; } /// /// Constructor /// /// Type of the value /// Rendering of the value as text /// Additional properties for this value public LogValue(Utf8String type, string text, Dictionary? properties = null) { Type = type; Text = text; Properties = properties; } /// /// Construct a source file log value with an overridden display text /// /// Source file to reference /// Display text for the fiel public static LogValue SourceFile(FileReference file, string text) { return new LogValue(LogValueType.SourceFile, text, new Dictionary { [LogEventPropertyName.File] = file.FullName }); } /// /// Constructs a value which contains a hyperlink to an external page /// /// Target URL public static LogValue Link(Uri target) { return Link(target, target.ToString()); } /// /// Constructs a value which contains a hyperlink to an external page /// /// Target URL /// Text to render for the link public static LogValue Link(Uri target, string text) { return new LogValue(LogValueType.Link, text, new Dictionary { [LogEventPropertyName.Target] = target.ToString() }); } /// /// Creates a LogValue from an object, overriding the type and display text for it /// /// The object to construct from /// public static LogValue FromObject(object obj) => FromObject(LogValueType.Object, obj.ToString() ?? String.Empty, obj); /// /// Creates a LogValue from an object, overriding the type and display text for it /// /// Type of the object /// Rendered representation of the object in the output string /// The object to construct from /// public static LogValue FromObject(Utf8String type, string text, object obj) { Type objType = obj.GetType(); Dictionary? properties = null; foreach (PropertyInfo propertyInfo in objType.GetProperties()) { if (propertyInfo.GetCustomAttribute() == null) { string name = propertyInfo.GetCustomAttribute()?.Name ?? propertyInfo.Name; properties ??= []; properties[new Utf8String(name)] = propertyInfo.GetValue(obj)!; } } return new LogValue(type, text, properties); } /// public override string ToString() { return Text; } } }