vip32 / serilog-sinks-litedb

Apache License 2.0
33 stars 15 forks source link

How to show a log entry in a DataGridView #10

Closed chris-kwng closed 4 years ago

chris-kwng commented 4 years ago

Do you know a simple way to convert a log entry from the LiteDB collection into an object?

My class ...

public class LogEntry
{
    [BsonField("_id")]
    public ObjectId Id { get; set; }
    [BsonField("_t")]
    public DateTime Time { get; set; }
    [BsonField("_ty")]
    public int Year { get; set; }
    [BsonField("_tm")]
    public int Month { get; set; }
    [BsonField("_td")]
    public int Day { get; set; }
    [BsonField("_tw")]
    public int Week { get; set; }
    [BsonField("_m")]
    public string Title { get; set; }
    [BsonField("_mt")]
    public string Description { get; set; }
    [BsonField("_i")]
    public string Index { get; set; }
    [BsonField("_l")]
    public string Level { get; set; }
}

... and the following code ...


using (var db = new LiteDatabase($"filename={Path.Combine(BasicSettings.AppPath, "Logs.db")};Mode=ReadOnly"))
{
    var col = db.GetCollection<LogEntry>(Program.Settings.TaskName);
    var data = col.FindAll().OrderBy(x => x.Time);

        DateTime test;
    foreach (var log in data) // pow
    {
        test = log.Time;
    }

        using (var reader = ObjectReader.Create(data, "Time", "Level", "Title", "Description"))
            dataTable.Load(reader); // pow

        var bindingSource = new BindingSource();

        bindingSource.DataSource = dataTable;
}

... does not work, but the field names should be right.

vip32 commented 4 years ago

Sorry, not so into datatables. How does it blow?

On Fri, Apr 17, 2020, 19:07 Christian Köwing notifications@github.com wrote:

Do you know a simple way to convert a log entry from the LiteDB collection into an object?

My class ...

public class LogEntry { [BsonField("_id")] public ObjectId Id { get; set; } [BsonField("_t")] public DateTime Time { get; set; } [BsonField("_ty")] public int Year { get; set; } [BsonField("_tm")] public int Month { get; set; } [BsonField("_td")] public int Day { get; set; } [BsonField("_tw")] public int Week { get; set; } [BsonField("_m")] public string Title { get; set; } [BsonField("_mt")] public string Description { get; set; } [BsonField("_i")] public string Index { get; set; } [BsonField("_l")] public string Level { get; set; } }

... and the following code ...

using (var db = new LiteDatabase($"filename={Path.Combine(BasicSettings.AppPath, "Logs.db")};Mode=ReadOnly")) { var col = db.GetCollection(Program.Settings.TaskName); var data = col.FindAll().OrderBy(x => x.Time);

    DateTime test;

foreach (var log in data) // pow { test = log.Time; }

    using (var reader = ObjectReader.Create(data, "Time", "Level", "Title", "Description"))
        dataTable.Load(reader); // pow

    var bindingSource = new BindingSource();

    bindingSource.DataSource = dataTable;

}

... does not work, but the field names should be right.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/vip32/serilog-sinks-litedb/issues/10, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABIDTZR4HBVLQHITCELF23RNCEDLANCNFSM4MK43JYQ .

chris-kwng commented 4 years ago

Hi Vincent,

I think I have found the problem. There seems to be a bug in the class 'LiteDbJsonFormatter' which causes that there are always two double curved brackets at the beginning and at the end.

{{"_id":{"$oid":"5e9884a0f4adba59e49a2425"},"_t":"2020-04-16T16:15:27.0491671Z","_ty":2020,"_tm":4,"_td":107,"_tw":16,"_m":"The connection-string is valid!","_mt":"The connection-string is valid!","_i":"6025ec58","_l":"Information"}}

However, this is not JSON standard and means that I cannot convert entries into an object.

image

Best regards, Chris

chris-kwng commented 4 years ago

Or maybe not!

'ToString' removes the double brackets... image

...and 'Deserialize' adds them back! image

I'm confused!

chris-kwng commented 4 years ago

Hi @vip32

I finally found the error. It is actually in the LiteDbJsonFormatter, in the method 'FormatEvent'. You store the log timestamp there as a string instead of as DateTime.

It's supposed to look like that: "t_":{ "$date": "2015-01-01T00:00:00Z" }

See also here: https://github.com/mbdavid/LiteDB/wiki/Data-Structure#json-extended

Here for you the corrected code (the old code is commented out):

public static void FormatEvent(LogEvent logEvent, TextWriter output, JsonValueFormatter valueFormatter)
{
    if (logEvent == null) throw new ArgumentNullException(nameof(logEvent));
    if (output == null) throw new ArgumentNullException(nameof(output));
    if (valueFormatter == null) throw new ArgumentNullException(nameof(valueFormatter));

    //output.Write("{\"_t\":\"");
    output.Write("{\"_t\":");
    //output.Write(logEvent.Timestamp.UtcDateTime.ToString("O"));
    output.Write($"{{ \"$date\": \"{logEvent.Timestamp.UtcDateTime.ToString("O")}\" }}");
    //output.Write("\",\"_ty\":");
    output.Write(",\"_ty\":");

    ...
}

What a waste of time! I was just on the wrong track. 😃

PS: Can you tell me what the field '_r' (Array) stands for? R for aRRay? ...for propeRty token?

Thanks and best regards,

Chris

vip32 commented 4 years ago

yes _r contains the properties

vip32 commented 4 years ago

@CKoewing I updated the code with yours, new nuget is available. hope it works better now https://www.nuget.org/packages/Serilog.Sinks.LiteDB/1.0.18

chris-kwng commented 4 years ago

THX! 🙂