0

I have a list of logs as a string. It is being output to me like this:

"2018.07.26 10:35:06:7889: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",
"2018.07.26 10:35:06:7959: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Requested (SOCS)... Success",
"2018.07.26 10:35:06:9019: DAIW - New Session Requested... Success (Start Session Thread Started)",
"2018.07.26 10:35:06:9169: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Thread (SOCS)... Success",
"2018.07.26 10:35:06:9229: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",
"2018.07.26 10:35:07:1219: DAIW - Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)",
"2018.07.26 10:35:07:1229: c0c2311a-b509-4e6e-a236-80e2d86f2647 - Client Successfully Retrieved Session",
"2018.07.26 10:35:07:1429: 4d50b064-d269-4256-a187-82a3f9402735 - End Session Requested - Thread started"

This is in the wrong order. It should be in this order:

"2018.07.26 10:35:06:7889: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",
"2018.07.26 10:35:06:7959: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Requested (SOCS)... Success",
"2018.07.26 10:35:06:9169: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Thread (SOCS)... Success",
"2018.07.26 10:35:06:9229: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",,
"2018.07.26 10:35:07:1429: 4d50b064-d269-4256-a187-82a3f9402735 - End Session Requested - Thread started"
"2018.07.26 10:35:06:9019: DAIW - New Session Requested... Success (Start Session Thread Started)",
"2018.07.26 10:35:07:1219: DAIW - Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)",
"2018.07.26 10:35:07:1229: c0c2311a-b509-4e6e-a236-80e2d86f2647 - Client Successfully Retrieved Session"

It appears the old system is just ordering by date. I have created a model and extracted the parts that I need. The model looks like this:

public class TroposLog
{
    public DateTime Created { get; set; }
    public string UserName { get; set; }
    public string SessionId { get; set; }
    public string ActionName { get; set; }
    public string Message { get; set; }
}

Now that gives me something to work with. But I can't get it to be ordered in the way I wanted. If I do this:

return troposLogs
           .OrderBy(m => m.UserName)
           .ThenBy(m => m.SessionId)
           .ThenBy(m => m.Created);

It returns this order:

"2018.07.26 10:35:06:7889: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",
"2018.07.26 10:35:06:7959: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Requested (SOCS)... Success",
"2018.07.26 10:35:06:9169: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Thread (SOCS)... Success",
"2018.07.26 10:35:06:9229: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",
"2018.07.26 10:35:07:1429: 4d50b064-d269-4256-a187-82a3f9402735 - End Session Requested - Thread started",
"2018.07.26 10:35:07:1229: c0c2311a-b509-4e6e-a236-80e2d86f2647 - Client Successfully Retrieved Session",
"2018.07.26 10:35:06:9019: DAIW - New Session Requested... Success (Start Session Thread Started)",
"2018.07.26 10:35:07:1219: DAIW - Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)"

I have also tried:

return troposLogs.OrderBy(m => m.UserName != null).ThenBy(m => m.UserName);

Which returns this order:

"2018.07.26 10:35:06:7889: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",
"2018.07.26 10:35:06:7959: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Requested (SOCS)... Success",
"2018.07.26 10:35:06:9169: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Thread (SOCS)... Success",
"2018.07.26 10:35:06:9229: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",
"2018.07.26 10:35:07:1229: c0c2311a-b509-4e6e-a236-80e2d86f2647 - Client Successfully Retrieved Session",
"2018.07.26 10:35:07:1429: 4d50b064-d269-4256-a187-82a3f9402735 - End Session Requested - Thread started",
"2018.07.26 10:35:06:9019: DAIW - New Session Requested... Success (Start Session Thread Started)",
"2018.07.26 10:35:07:1219: DAIW - Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)"

In this case, the date has taken over. But I need the session id to stay together.

Could someone help me with this?

This is an example of a tropos log (I have ignored data types, it is simply to show you how it ties to the string logs)

var logString = "2018.07.26 10:35:06:7889: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result";
var log = new TroposLog();
log.Created = "2018.07.26 10:35:06:7889";
log.SessionId = "4d50b064-d269-4256-a187-82a3f9402735";
log.Message = "Client successfully got the transaction result";

The log above, has no UserName or ActionName;

var logString = "2018.07.26 10:35:07:1219: DAIW - Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)";
var log = new TroposLog();
log.Created = "2018.07.26 10:35:07:1219";
log.SessionId = "4d50b064-d269-4256-a187-82a3f9402735";
log.Message = "Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)";
log.UserName= "DAIW";

This one has no ActionName. And finally:

var logString = "2018.07.26 10:35:06:9169: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Thread (SOCS)... Success";
var log = new TroposLog();
log.Created = "2018.07.26 10:35:06:9169";
log.SessionId = "4d50b064-d269-4256-a187-82a3f9402735";
log.Message = "Run Transaction Thread (SOCS)... Success";
log.ActionName= "SOCS";

This one has no UserName. I hope that helps to clarify

r3plica
  • 13,017
  • 23
  • 128
  • 290
  • 1
    I can´t see how the log-messages are reflected in your data-structure. I see a date followed by some kind of identifier and then a message. But what´s with `ActionName`, `UserName` and `SessionID`? – MakePeaceGreatAgain Jul 26 '18 at 14:27
  • Possible duplicate of [LINQ order by null column where order is ascending and nulls should be last](https://stackoverflow.com/questions/6461479/linq-order-by-null-column-where-order-is-ascending-and-nulls-should-be-last) – Martin Backasch Aug 28 '18 at 06:34

2 Answers2

3

Try:

troposLogs.OrderBy(m => m.UserName == null).ThenBy(m => m.UserName)

So UserName == null is true, UserName != null is false, and the ordering of bool values is false, true.

Your error is that you are ordering first by UserName and then by UserName "is null"... But this second ordering is useless (because ordering by UserName has already ordered dividing null and not null). You must do the opposite (as I've done).

Test:

var troposLogs = new List<TroposLog>();

var log = new TroposLog();
log.Created = DateTime.ParseExact("2018.07.26 10:35:06:7889", @"yyyy\.MM\.dd HH\:mm\:ss\:ffff", CultureInfo.InvariantCulture);
log.SessionId = "4d50b064-d269-4256-a187-82a3f9402735";
log.Message = "Client successfully got the transaction result";
troposLogs.Add(log);

log = new TroposLog();
log.Created = DateTime.ParseExact("2018.07.26 10:35:07:1219", @"yyyy\.MM\.dd HH\:mm\:ss\:ffff", CultureInfo.InvariantCulture);
log.SessionId = "4d50b064-d269-4256-a187-82a3f9402735";
log.Message = "Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)";
log.UserName = "DAIW";
troposLogs.Add(log);

log = new TroposLog();
log.Created = DateTime.ParseExact("2018.07.26 10:35:06:9169", @"yyyy\.MM\.dd HH\:mm\:ss\:ffff", CultureInfo.InvariantCulture);
log.SessionId = "4d50b064-d269-4256-a187-82a3f9402735";
log.Message = "Run Transaction Thread (SOCS)... Success";
log.ActionName = "SOCS";
troposLogs.Add(log);

var ordered = troposLogs.OrderBy(m => m.UserName == null)
            .ThenBy(m => m.UserName)
            .ThenBy(m => m.SessionId)
            .ThenBy(m => m.Created)
            .ToArray();
xanatos
  • 109,618
  • 12
  • 197
  • 280
1

What you really want is to group the logs by SessionId and then order each group by date (I think) so you can try this:

        var troposLogs = new TroposLog[]
        {
            new TroposLog
            {
                Created = DateTime.Now, 
                UserName = null,
                SessionId = "4d50b064-d269-4256-a187-82a3f9402735",
                ActionName = null,
                Message = "Client successfully got the transaction result"
            },
            new TroposLog
            {
                Created = DateTime.Now,
                UserName = null,
                SessionId = "4d50b064-d269-4256-a187-82a3f9402735",
                ActionName = "SOCS",
                Message = "Run Transaction Requested (SOCS)... Success"
            },
            new TroposLog
            {
                Created = DateTime.Now,
                UserName = "DAIW",
                SessionId = "c0c2311a-b509-4e6e-a236-80e2d86f2647",
                ActionName = null,
                Message = "New Session Requested... Success (Start Session Thread Started)"
            },
            new TroposLog
            {
                Created = DateTime.Now,
                UserName = null,
                SessionId = "4d50b064-d269-4256-a187-82a3f9402735",
                ActionName = "SOCS",
                Message = "Run Transaction Thread (SOCS)... Success"
            },
            new TroposLog
            {
                Created = DateTime.Now,
                UserName = null,
                SessionId = "4d50b064-d269-4256-a187-82a3f9402735",
                ActionName = null,
                Message = "Client successfully got the transaction result"
            },
            new TroposLog
            {
                Created = DateTime.Now,
                UserName = "DAIW",
                SessionId = "c0c2311a-b509-4e6e-a236-80e2d86f2647",
                ActionName = null,
                Message = "Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)"
            },
            new TroposLog
            {
                Created = DateTime.Now,
                UserName = null,
                SessionId = "c0c2311a-b509-4e6e-a236-80e2d86f2647",
                ActionName = null,
                Message = "Client Successfully Retrieved Session"
            },
            new TroposLog
            {
                Created = DateTime.Now,
                UserName = null,
                SessionId = "4d50b064-d269-4256-a187-82a3f9402735",
                ActionName = "",
                Message = "End Session Requested - Thread started"
            },
        };

        var orderedLogs = troposLogs.OrderBy(l => l.Created) // Just in case
                                    .GroupBy(l => l.SessionId)
                                    .OrderBy(g => g.FirstOrDefault().Created)
                                    .SelectMany(g => g)
                                    .ToList();

Note: To get this working, you need to assign the correct sessionIds to all log entries when you fill your model, e.g. all logs for 'DAIW' user should have sessionId 'c0c2311a-b509-4e6e-a236-80e2d86f2647' which is the correct one according your input data (this should not be a big deal)

Hope this helps you

Eddy
  • 473
  • 5
  • 9