-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature] Add "event id" column or object #77
Comments
Here is a working implementation using the murmur3 algorithm. First install package:
using System.Text;
using Murmur;
using Serilog.Core;
using Serilog.Events;
namespace Serilog.Enrichers;
public sealed class EventIdEnricher : ILogEventEnricher
{
public const string COLUMN_NAME = "EventId";
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
ArgumentNullException.ThrowIfNull(logEvent, nameof(logEvent));
ArgumentNullException.ThrowIfNull(propertyFactory, nameof(propertyFactory));
var eventId = ComputeHash(logEvent.MessageTemplate.Text);
var property = propertyFactory.CreateProperty(COLUMN_NAME, eventId);
logEvent.AddPropertyIfAbsent(property);
}
public static string ComputeHash(string messageTemplate)
{
using var algorithm = MurmurHash.Create32();
var bytes = Encoding.UTF8.GetBytes(messageTemplate);
var hash = algorithm.ComputeHash(bytes);
//var numericHash = BitConverter.ToUInt32(hash, 0); // alternative
var hexadecimalHash = BitConverter.ToString(hash).Replace("-", "", StringComparison.Ordinal).ToLowerInvariant();
return hexadecimalHash;
}
}
using NpgsqlTypes;
using Serilog.Enrichers;
using Serilog.Events;
namespace Serilog.Sinks.PostgreSQL.ColumnWriters;
public sealed class EventIdColumnWriter : ColumnWriterBase
{
public EventIdColumnWriter() : base(NpgsqlDbType.Text, skipOnInsert:false, order:0) { }
public EventIdColumnWriter(NpgsqlDbType dbType = NpgsqlDbType.Text, int? order = null) : base(dbType, skipOnInsert:false, order) { }
public override object GetValue(LogEvent logEvent, IFormatProvider? formatProvider = null)
{
ArgumentNullException.ThrowIfNull(logEvent, nameof(logEvent));
// I'm unsure whether it is guaranteed that value already
// computed, so compute if necessary
var alreadyComputed = logEvent.Properties.TryGetValue(EventIdEnricher.COLUMN_NAME, out var logEventPropertyValue);
var eventId = alreadyComputed && logEventPropertyValue != null
? logEventPropertyValue.ToString()
: EventIdEnricher.ComputeHash(logEvent.MessageTemplate.Text);
return eventId;
}
} Config: var columns = new Dictionary<string, ColumnWriterBase>
{
{ EventIdEnricher.COLUMN_NAME, new EventIdColumnWriter() },
// etc...
};
services.AddSerilog((services, config) => config
.Enrich.With<EventIdEnricher>()
.WriteTo.PostgreSQL(/* ... */); |
IGNORE THE PREVIOUS IMPLEMENTATIONThis is the one I now use, which is simpler and does not require external dependencies. Reference hashing algorithmReference either An alternative is to simply copy/paste the algorithm as it is really simple. Create
|
It's a good idea to store a hash of the message template, so one can easily search for similar events.
(By the way, Seq also does this.)
One computes the hash using one of these algorithms:
Then the hash must be persisted:
EventIdEnricher
) can add it as a property to the log event, which would be serialised to the "Properties" JSON objectEventIdColumnWriter
)The text was updated successfully, but these errors were encountered: