Solved

Serilog logger question

Posted on 2015-01-24
17
162 Views
Last Modified: 2015-01-28
Hello,
I am using Serilog for the first time to perform logging. I am outputting to a text files with the following statement:

MyGlobals.logger.Debug("Test1 User: {UserName} ", MyExe.userId);

I am getting the following output:
2015-01-24 19:26:11.965 +00:00 [Debug] Test1 User: "pclarkeirl"
This works well.

I now want to be able to make the output more configurable by passing in the text and variables that are to be output by the logger.

MyGlobals.logger.Debug(message);
Where message is set to  “Test1 User: {UserName}, MyExe.userId”

However I am getting the following output:
2015-01-24 19:26:14.245 +00:00 [Debug] Test1 User: {UserName}, MyExe.userId
It is treating the whole line as text.

Is there any way that I can pass the logger message in as a variable and have it displayed correctly?

regards
Pat
0
Comment
Question by:pclarke7
  • 9
  • 8
17 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 40570656
It doesn't look like you are passing in the data to the call.

Example:

http://serilog.net/

log.Information("Processed {@Position} in {Elapsed:000} ms.", position, elapsedMs);
0
 

Author Comment

by:pclarke7
ID: 40571158
Hi Bob,
 you are right, my data is coming in as text. Taking your example, what if I wanted to build the string

Processed {@Position} in {Elapsed:000} ms.", position, elapsedMs


 rather than hardcode it. First I would get the text portion

 myString="Processed {@Position} in {Elapsed:000} ms."

 but how can I append the positions,elapsedMs
 without making the whole thing a string ?

 regards
 Pat
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 40571199
The signature for that method is:

Serilog.Log.Debug(string, params object[])

Open in new window


All you would need to do is pass in an array of objects.

This would be equivalent to your first statement:

var valueList = new object[] {  MyExe.userId };
MyGlobals.logger.Debug("Test1 User: {UserName} ", valueList);

Open in new window

0
 

Author Comment

by:pclarke7
ID: 40571234
Hi Bob,
I think you are missing what I am trying to achieve. I know that I can log successfully by issuing a statement like   MyGlobals.logger.Debug("Test1 User: {UserName} ", MyExe.userId );  but I want the flexibility to have the text and variables passed to the logger at run time.

MyGlobals.logger.Debug("variable text {A} {B} {C}", varfield1,varfield2,varfield3)

but when I try to build this string I get:
"variable text {A} {B} {C}, varfield1 , varfield2,varfield3"

instead of

"variable text {A} {B} {C}" ,  varfield1,varfield2,varfield3

regards
Pat
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 40571252
Are you building the string like this?

MyGlobals.logger.Debug("variable text {A} {B} {C}", varfield1,varfield2,varfield3);

Open in new window

0
 

Author Comment

by:pclarke7
ID: 40571454
Yes,
that's how I'm trying to build the string but it is interpreting everything as belonging inside double quotes. I am not sure how to change it so it can interpret the 3 fields as fields.

I'm getting this:   MyGlobals.logger.Debug("variable text {A} {B} {C}, varfield1,varfield2,varfield3)";

what I want is this: MyGlobals.logger.Debug("variable text {A} {B} {C}", varfield1,varfield2,varfield3);

the difference being the quotes
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 40571473
What are the values for varfield1,varfield2,varfield3?
0
 

Author Comment

by:pclarke7
ID: 40572313
These values will vary. The application looks at the transaction type being processed and will set a different value based on the type.

Trans type 'D'  will have varfield values of  'userId, transactionId, FieldValuesDict'
Trans type 'I'    will have varfield values of  'userId, transactionId, InputValuList, OutputValuList'
etc...

regards
Pat
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 96

Expert Comment

by:Bob Learned
ID: 40573234
If you do this:

MyGlobals.logger.Debug("variable text {A} {B} {C}", varfield1,varfield2,varfield3);

Open in new window


where varfield1 = userId, varfield2 = "transactionId", varfield3 = "FieldValuesDict",

what do you want to show in the log?
0
 

Author Comment

by:pclarke7
ID: 40573537
The user decides what viarables (from a list of dozens of available variables) that they want to view on the logger by transactions. So 1 user might decide that they just want to see the values dictionary for transaction type 'D' whilst another might want to log the full list of  variables available.

This is why I am trying to build the logger statement at run time rather than hard code it.

regards
Pat
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 40573657
I am certainly not seeing the "big picture" here, so if I understand what you are looking for, it would be something like this Windows Forms example (with a ListBox):

            var valueList = new List<object>();

            var builder = new StringBuilder();

            var count = 0;

            for (var i = 0; i < listBox1.Items.Count; i++)
            {
                if (listBox1.GetSelected(i))
                {
                    var text = listBox1.Items[i].ToString();

                    builder.Append("{");
                    builder.Append((char)(i + 65));
                    builder.Append("} ");

                    switch (text)
                    {
                        case "userId":
                            valueList.Add(data.userId);
                            break;

                        case "transactionId":
                            valueList.Add(data.transactionId);
                            break;

                        case "FieldValuesDict":
                            valueList.Add(data.FieldValuesDict);
                            break;
                    }
                }
            }

            var message = "variable text " + builder.ToString();

            MyGlobals.logger.Debug(message, values.ToArray());

Open in new window

0
 

Author Comment

by:pclarke7
ID: 40574065
Hi Bob,
yes, I think your example is close. I have simplified it below:

                    var text = "THIS IS A TEST:";
                    string[] list1 ={"User name:", "Transaction:" ,"Transaction values:"};
                    string[] list2 = { "MyUser.userId", "MyTransSeq.transactionId", "MyVarValueDict" };
                    for(int j=0; j< list1.Length; j++)
                    {
                        text = text + list1[j] + " {"+j+"} ";
                    }
                  MyGlobals.logger.Information(text, list2.ToArray());
 
At the time of running
MyUser.userId='pclarkeirl' ,
MyTransSeq.transactionId='initmenu01'
MyVarValueDict=  various values
text="THIS IS A TEST:User name: {0} Transaction: {1} Transaction values: {2} "

The output of the  logger is:
2015-01-27 22:40:55.110 +00:00 [Information] THIS IS A TEST:User name: ["MyUser.userId", "MyTransSeq.transactionId", "MyVarValueDict"] Transaction: {1} Transaction values: {2}

It seems to have taken the 3 values in list 2 and assumed they were just 1 value belonging to {0} rather than 3 values belonging to {0},{1},{2}. Any idea how I can get the value of list2 to appear as 3 literals ?

regards
Pat
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 40574360
How are you creating the logger?  

What type of sink are you using?
0
 

Author Comment

by:pclarke7
ID: 40574683
Hi Bob,
just writing to a text file. The logger works perfectly when I hard code the values such as

MyGlobals.logger.Information(User name: {0} Transaction: {1} Transaction values: {2} ,MyUser.userId, MyTransSeq.transactionId, MyVarValueDict)

The issue is getting the variable to be seen as literals rather than text enclosed in " ". I'm not sure how to achieve this ?

regards
Pat
0
 
LVL 96

Accepted Solution

by:
Bob Learned earned 500 total points
ID: 40575367
This is tricky--reviewing the signature (Debug(string, params object[]), you would need an object array, not a string array.  I don't believe that the compiler will map the parameter objects otherwise.  

Try this instead:

 var text = "THIS IS A TEST:";
                    string[] list1 ={"User name:", "Transaction:" ,"Transaction values:"};
                    var list2 = new object[] { MyUser.userId, MyTransSeq.transactionId, MyVarValueDict };
                    for(int j=0; j< list1.Length; j++)
                    {
                        text = text + list1[j] + " {"+j+"} ";
                    }
                  MyGlobals.logger.Information(text, list2.ToArray());

Open in new window

0
 

Author Comment

by:pclarke7
ID: 40576103
Hi Bob,
Works like a charm.


2015-01-28 20:56:09.146 +00:00 [Information] THIS IS A TEST:User name: "pclarkeirl" Transaction: "initmenu01" Transaction values: [("<&option>": " "), ("<&envname>": "prod"), ("<&test>": "MYTESTVALU"), ("<&envcount>": "3"), ("<&companyid>": "strykerlmk"), ("<&envdesc1>": "Production Env"), ("<&envdesc2>": "Limerick Production environment"), ("<&envcolour>": "green"), ("<&count>": " "), ("<&selopt>": " ")]


thank you for all of your help on this. points certainly earned.

regards
Pat
0
 

Author Closing Comment

by:pclarke7
ID: 40576105
thanks for your patience
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Bit flags and bit flag manipulation is perhaps one of the most underrated strategies in programming, likely because most programmers developing in high-level languages rely too much on the high-level features, and forget about the low-level ones. Th…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now