Files
EonaCat.LogStack/EonaCat.LogStack/EonaCatLoggerCore/Flows/TransformFlow.cs
T
2026-07-21 11:23:19 +02:00

108 lines
3.9 KiB
C#

using EonaCat.LogStack.Core;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace EonaCat.LogStack.Flows
{
// This file is part of the EonaCat project(s) which is released under the Apache License.
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
/// <summary>
/// A flow that transforms log events before passing them to an inner flow.
/// Allows modification of messages, properties, and other attributes.
/// </summary>
public sealed class TransformFlow : FlowBase
{
private readonly IFlow _innerFlow;
private readonly Func<LogEvent, LogEvent> _transformer;
public TransformFlow(
IFlow innerFlow,
Func<LogEvent, LogEvent> transformer,
LogLevel minimumLevel = LogLevel.Trace)
: base(innerFlow?.Name + "_Transform" ?? "TransformFlow", minimumLevel)
{
_innerFlow = innerFlow ?? throw new ArgumentNullException(nameof(innerFlow));
_transformer = transformer ?? throw new ArgumentNullException(nameof(transformer));
}
public override async Task<WriteResult> BlastAsync(LogEvent logEvent, CancellationToken cancellationToken = default)
{
if (!IsEnabled || !IsLogLevelEnabled(logEvent))
{
return WriteResult.LevelFiltered;
}
try
{
var transformedEvent = _transformer(logEvent);
var result = await _innerFlow.BlastAsync(transformedEvent, cancellationToken).ConfigureAwait(false);
if (result == WriteResult.Success)
{
Interlocked.Increment(ref BlastedCount);
}
else
{
Interlocked.Increment(ref DroppedCount);
}
return result;
}
catch (Exception ex)
{
Interlocked.Increment(ref DroppedCount);
System.Diagnostics.Debug.WriteLine($"TransformFlow error: {ex.Message}");
return WriteResult.Failed;
}
}
public override async Task<WriteResult> BlastBatchAsync(ReadOnlyMemory<LogEvent> logEvents, CancellationToken cancellationToken = default)
{
if (!IsEnabled)
{
return WriteResult.FlowDisabled;
}
var eventsArray = logEvents.ToArray();
var transformedEvents = new List<LogEvent>();
foreach (var logEvent in eventsArray)
{
if (IsLogLevelEnabled(logEvent))
{
try
{
var transformed = _transformer(logEvent);
transformedEvents.Add(transformed);
Interlocked.Increment(ref BlastedCount);
}
catch (Exception ex)
{
Interlocked.Increment(ref DroppedCount);
System.Diagnostics.Debug.WriteLine($"TransformFlow batch error: {ex.Message}");
}
}
}
if (transformedEvents.Count > 0)
{
return await _innerFlow.BlastBatchAsync(transformedEvents.ToArray(), cancellationToken).ConfigureAwait(false);
}
return WriteResult.Success;
}
public override async Task FlushAsync(CancellationToken cancellationToken = default)
{
await _innerFlow.FlushAsync(cancellationToken).ConfigureAwait(false);
}
public override async ValueTask DisposeAsync()
{
await _innerFlow.DisposeAsync().ConfigureAwait(false);
await base.DisposeAsync().ConfigureAwait(false);
}
}
}