mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
129 lines
4.0 KiB
C#
129 lines
4.0 KiB
C#
namespace Divergic.Logging.Xunit
|
|
{
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.Text.Json;
|
|
using global::Xunit.Abstractions;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
internal class ScopeWriter : IDisposable
|
|
{
|
|
private readonly string _category;
|
|
private readonly LoggingConfig _config;
|
|
private readonly int _depth;
|
|
private readonly Action _onScopeEnd;
|
|
private readonly ITestOutputHelper _output;
|
|
private readonly object? _state;
|
|
private string _scopeMessage = string.Empty;
|
|
private string _structuredStateData = string.Empty;
|
|
|
|
public ScopeWriter(
|
|
ITestOutputHelper output,
|
|
object? state,
|
|
int depth,
|
|
string category,
|
|
Action onScopeEnd,
|
|
LoggingConfig config)
|
|
{
|
|
_output = output;
|
|
_state = state;
|
|
_depth = depth;
|
|
_category = category;
|
|
_onScopeEnd = onScopeEnd;
|
|
_config = config;
|
|
|
|
DetermineScopeStateMessage();
|
|
|
|
var scopeStartMessage = BuildScopeStateMessage(false);
|
|
|
|
WriteLog(_depth, scopeStartMessage);
|
|
|
|
if (string.IsNullOrWhiteSpace(_structuredStateData) == false)
|
|
{
|
|
// Add the padding to the structured data
|
|
var structuredLines =
|
|
_structuredStateData.Split(new[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
WriteLog(_depth + 1, "Scope data: ");
|
|
|
|
foreach (var structuredLine in structuredLines)
|
|
{
|
|
WriteLog(_depth + 1, structuredLine);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void WriteLog(int depth, string message)
|
|
{
|
|
var formattedMessage = _config.ScopeFormatter.Format(depth, _category, LogLevel.Information, 0, message, null);
|
|
|
|
_output.WriteLine(formattedMessage);
|
|
|
|
// Write the message to the output window
|
|
Trace.WriteLine(formattedMessage);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
var scopeStartMessage = BuildScopeStateMessage(true);
|
|
|
|
_output.WriteLine(scopeStartMessage);
|
|
|
|
_onScopeEnd.Invoke();
|
|
}
|
|
|
|
private string BuildScopeStateMessage(bool isScopeEnd)
|
|
{
|
|
var endScopeMarker = isScopeEnd ? "/" : string.Empty;
|
|
const string format = "<{0}{1}>";
|
|
|
|
var message = string.Format(CultureInfo.InvariantCulture, format, endScopeMarker, _scopeMessage);
|
|
|
|
var formattedMessage =
|
|
_config.ScopeFormatter.Format(_depth, _category, LogLevel.Information, 0, message, null);
|
|
|
|
return formattedMessage;
|
|
}
|
|
|
|
private void DetermineScopeStateMessage()
|
|
{
|
|
const string scopeMarker = "Scope: ";
|
|
var defaultScopeMessage = "Scope " + (_depth + 1);
|
|
|
|
if (_state == null)
|
|
{
|
|
_scopeMessage = defaultScopeMessage;
|
|
}
|
|
else if (_state is string state)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(state))
|
|
{
|
|
_scopeMessage = defaultScopeMessage;
|
|
}
|
|
else
|
|
{
|
|
_scopeMessage = scopeMarker + state;
|
|
}
|
|
}
|
|
else if (_state.GetType().IsValueType)
|
|
{
|
|
_scopeMessage = scopeMarker + _state;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
// The data is probably a complex object or a structured log entry
|
|
_structuredStateData = JsonSerializer.Serialize(_state, SerializerSettings.Default);
|
|
}
|
|
catch (JsonException ex)
|
|
{
|
|
_structuredStateData = ex.ToString();
|
|
}
|
|
|
|
_scopeMessage = defaultScopeMessage;
|
|
}
|
|
}
|
|
}
|
|
} |