Vostok.Logging
HomeQuickstartModulesImplementations
1.0.0
1.0.0
  • Home
  • Quickstart
  • Guarantees
  • Configuration
  • Concepts and basics
    • Log interface
    • Log events
    • Syntax
      • Logging extensions
      • Message templates
      • Providing property values
    • Formatting
      • Output templates
      • Special properties
      • Format specifiers
    • Source context
    • Operation context
  • Modules
    • Abstractions
    • Configuration
    • Formatting
    • Console
    • File
    • Hercules
    • Context
    • Serilog
    • Log4net
    • NUnit
    • Microsoft
  • Implementations
    • Silent log
    • Console log
    • File log
    • Hercules log
  • Integrations
    • Serilog integration
    • Log4net integration
    • Microsoft logging integration
  • How-to guides
    • Using operation context
    • Using static log provider
    • Filtering events
    • Enriching events
    • Transforming events
    • Combining multiple logs
    • Custom output templates
    • External configuration rules
Powered by GitBook
On this page
  • 1. Pass property values as optional object arguments:
  • 2. Use a single object with named properties:
  • 3. Use positional placeholders:
  • 4. Use interpolated strings with C# 10:
  1. Concepts and basics
  2. Syntax

Providing property values

PreviousMessage templatesNextFormatting

Last updated 2 years ago

There are several supported ways to pass property values for placeholders in when using .

1. Pass property values as optional object arguments:

log.Info("Welcome, {User}. You have {UnreadCount} unread messages.", "Jenny", 2);

Property names are inferred from placeholders in message template.

If arguments count exceeds template placeholders count, excess arguments are named with numbers denoting their positions:

log.Info("Welcome, {User}.", "Jenny", "foo", "bar");
// produced event properties: {"User": "Jenny", "1": "foo", "2": "bar"}

If provided arguments count is not sufficient to account for all template placeholders, the names for existing arguments are still inferred.

Strictly speaking, this approach does not support multiple occurrences of the same placeholder name within a message template (last matched argument wins):

log.Info("Welcome, {name}. {name}, you have {count} unread messages.", 
    "Jenny", 10);
// The result is: "Welcome, 10. 10, you have  unread messages."

Although it's safe to use if all duplicate placeholder occurrences in the template are located far enough not to get matched to any arguments:

log.Info("Welcome, {name}. You have {count} unread messages, {name}.",
    "Jenny", 10);
// The result is: Welcome, Jenny. You have 10 unread messages, Jenny.

2. Use a single object with named properties:

 log.Info("Welcome, {User}. You have {UnreadCount} unread messages.", 
     new {User = "Jenny", UnreadCount = 2});

When using this syntax, user is responsible for making sure that object property names match the names of placeholders in message template.

3. Use positional placeholders:

log.Info("Welcome, {0}. You have {1} unread messages.", "Jenny", 2);

Despite being somewhat deprecated nowadays, this syntax enables gradual migration from libraries that do not support structured logging.

It also supports multiple occurrences of the same placeholder within a single template:

log.Info("Welcome, {0}. {0}, you have {1} unread messages.", "Jenny", 2);

4. Use interpolated strings with C# 10:

var User = "Jenny";
var UnreadCount = 2;
log.Info($"Welcome, {User}. You have {UnreadCount} unread messages.");
// produced message template: "Welcome, {User}. You have {UnreadCount} unread messages."
// produced event properties: {"User": "Jenny", "UnreadCount": 2}

When using this syntax, user is responsible for making sure that new C# 10 features are enabled and Vostok.Logging.Abstractions library targets .NET 6.

log.Info($"Welcome, {User,10}. You have {UnreadCount:D5} unread messages.");

If you want to disable automatic properties extraction from an interpolated string directly cast it to the string:

log.Info($"Welcome, {User}. You have {UnreadCount} unread messages.".ToString());
log.Info((string)$"Welcome, {User}. You have {UnreadCount} unread messages.");

Or disable it entirely for your application:

LogExtensions_Interpolated.Enabled = false;

For the same reasons, do not pass properties with invalid names (such as function calls). Instead of:

log.Info($"Welcome, {User}. You have {Random.Shared.Next()} unread messages.");
// produced message template: "Welcome, {User}. You have 623653080 unread messages."
// produced event properties: {"User": "Jenny"}

you should use:

log.Info($"Welcome, {User}. You have {{RandomNumber}} unread messages.", Random.Shared.Next());
// produced message template: "Welcome, {User}. You have {RandomNumber} unread messages."
// produced event properties: {"User": "Jenny", "RandomNumber": 623653080}

It also supports :

However, in this case, you may have performance issues (due to the internal templates cache) or corrupted messages (due to the rendering stage). See documentation for details.

message template
logging extensions
standard formatters
Message templates