using System.Diagnostics.Metrics;
using System.Runtime.CompilerServices;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace Terminal.Gui;
///
/// Singleton logging instance class. Do not use console loggers
/// with this class as it will interfere with Terminal.Gui
/// screen output (i.e. use a file logger).
///
///
/// Also contains the
/// instance that should be used for internal metrics
/// (iteration timing etc.).
///
public static class Logging
{
///
/// Logger, defaults to NullLogger (i.e. no logging). Set this to a
/// file logger to enable logging of Terminal.Gui internals.
///
public static ILogger Logger { get; set; } = NullLogger.Instance;
///
/// Metrics reporting meter for internal Terminal.Gui processes. To use
/// create your own static instrument e.g. CreateCounter, CreateHistogram etc
///
internal static readonly Meter Meter = new ("Terminal.Gui");
///
/// Metric for how long it takes each full iteration of the main loop to occur
///
public static readonly Histogram TotalIterationMetric = Meter.CreateHistogram ("Iteration (ms)");
///
/// Metric for how long it took to do the 'timeouts and invokes' section of main loop.
///
public static readonly Histogram IterationInvokesAndTimeouts = Meter.CreateHistogram ("Invokes & Timers (ms)");
///
/// Counter for when we redraw, helps detect situations e.g. where we are repainting entire UI every loop
///
public static readonly Counter Redraws = Meter.CreateCounter ("Redraws");
///
/// Metric for how long it takes to read all available input from the input stream - at which
/// point input loop will sleep.
///
public static readonly Histogram DrainInputStream = Meter.CreateHistogram ("Drain Input (ms)");
///
/// Logs an error message including the class and method name.
///
///
///
///
public static void Error (
string message,
[CallerMemberName] string caller = "",
[CallerFilePath] string filePath = ""
)
{
string className = Path.GetFileNameWithoutExtension (filePath);
Logger.LogError ($"[{className}] [{caller}] {message}");
}
///
/// Logs a fatal/critical message including the class and method name.
///
///
///
///
public static void Critical (
string message,
[CallerMemberName] string caller = "",
[CallerFilePath] string filePath = ""
)
{
string className = Path.GetFileNameWithoutExtension (filePath);
Logger.LogCritical ($"[{className}] [{caller}] {message}");
}
///
/// Logs a debug message including the class and method name.
///
///
///
///
public static void Debug (
string message,
[CallerMemberName] string caller = "",
[CallerFilePath] string filePath = ""
)
{
string className = Path.GetFileNameWithoutExtension (filePath);
Logger.LogDebug ($"[{className}] [{caller}] {message}");
}
///
/// Logs an informational message including the class and method name.
///
///
///
///
public static void Information (
string message,
[CallerMemberName] string caller = "",
[CallerFilePath] string filePath = ""
)
{
string className = Path.GetFileNameWithoutExtension (filePath);
Logger.LogInformation ($"[{className}] [{caller}] {message}");
}
///
/// Logs a trace/verbose message including the class and method name.
///
///
///
///
public static void Trace (
string message,
[CallerMemberName] string caller = "",
[CallerFilePath] string filePath = ""
)
{
string className = Path.GetFileNameWithoutExtension (filePath);
Logger.LogTrace ($"[{className}] [{caller}] {message}");
}
///
/// Logs a warning message including the class and method name.
///
///
///
///
public static void Warning (
string message,
[CallerMemberName] string caller = "",
[CallerFilePath] string filePath = ""
)
{
string className = Path.GetFileNameWithoutExtension (filePath);
Logger.LogWarning ($"[{className}] [{caller}] {message}");
}
}