Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 188
  • Last Modified:

Serilog logger question

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
pclarke7
Asked:
pclarke7
  • 9
  • 8
1 Solution
 
Bob LearnedCommented:
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
 
pclarke7Author Commented:
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
 
Bob LearnedCommented:
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
pclarke7Author Commented:
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
 
Bob LearnedCommented:
Are you building the string like this?

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

Open in new window

0
 
pclarke7Author Commented:
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
 
Bob LearnedCommented:
What are the values for varfield1,varfield2,varfield3?
0
 
pclarke7Author Commented:
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
 
Bob LearnedCommented:
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
 
pclarke7Author Commented:
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
 
Bob LearnedCommented:
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
 
pclarke7Author Commented:
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
 
Bob LearnedCommented:
How are you creating the logger?  

What type of sink are you using?
0
 
pclarke7Author Commented:
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
 
Bob LearnedCommented:
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
 
pclarke7Author Commented:
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
 
pclarke7Author Commented:
thanks for your patience
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 9
  • 8
Tackle projects and never again get stuck behind a technical roadblock.
Join Now