/

Fluent Syntax

ByteHide Logger supports fluent syntax, allowing you to chain multiple logging features in a single, readable call. This enables you to combine metadata, context, tags, correlation IDs, and logging levels seamlessly. Note that global configuration methods are not fluent and should be called separately.

Basic Fluent Chaining

Single Feature Chaining

// Metadata only
Log.WithMetadata("executionTime", 450)
   .Info("Operation completed");

// Context only
Log.WithContext("orderId", order.Id)
   .Error("Order validation failed");

// Tags only
Log.WithTags("database", "performance")
   .Warn("Query execution time exceeded");

// Correlation ID only
Log.WithCorrelationId("req-12345")
   .Info("Request processing started");

Multiple Feature Chaining

// Metadata + Context + Tags
Log.WithMetadata("responseTime", 2500)
   .WithContext("apiEndpoint", "/api/orders")
   .WithTags("api", "performance", "external")
   .Warn("API response time exceeded threshold");

// Context + Tags + Correlation ID
Log.WithCorrelationId("req-abc123")
   .WithContext("action", "login")
   .WithTags("authentication", "security")
   .Info("User login successful");

// All features combined
Log.WithCorrelationId("req-def456")
   .WithMetadata("processingTimeMs", 850)
   .WithContext("operation", "OrderProcessing")
   .WithTags("orders", "business-logic")
   .Info("Order processing completed");

Practical Examples

// Database operations
Log.WithMetadata("executionTimeMs", 1250)
   .WithMetadata("rowsAffected", 150)
   .WithContext("sqlQuery", "SELECT * FROM Orders WHERE Status = 'Pending'")
   .WithTags("database", "performance")
   .Warn("Slow query detected");

// API operations
Log.WithCorrelationId("req-abc123")
   .WithMetadata("responseTimeMs", 2500)
   .WithContext("endpoint", "/api/payments")
   .WithTags("api", "external", "timeout")
   .Error("External API timeout");

// Business operations
Log.WithMetadata("orderValue", 299.99m)
   .WithContext("orderId", order.Id)
   .WithContext("paymentMethod", "CreditCard")
   .WithTags("orders", "payment")
   .Info("Payment processing started");

Error Handling

try
{
    await ProcessOrderAsync(order);
}
catch (PaymentException ex)
{
    Log.WithCorrelationId("req-123")
       .WithMetadata("errorCode", ex.ErrorCode)
       .WithContext("orderId", order.Id)
       .WithContext("paymentMethod", order.PaymentMethod)
       .WithTags("payment", "error")
       .Error("Payment processing failed", ex);
}
catch (Exception ex)
{
    Log.WithCorrelationId("req-123")
       .WithContext("orderId", order.Id)
       .WithTags("orders", "error", "critical")
       .Error("Unexpected error during order processing", ex);
}

Performance Monitoring

var stopwatch = Stopwatch.StartNew();
var result = await ProcessOrderAsync(order);
stopwatch.Stop();

Log.WithCorrelationId("req-123")
   .WithMetadata("executionTimeMs", stopwatch.ElapsedMilliseconds)
   .WithContext("operation", "ProcessOrder")
   .WithContext("orderId", order.Id)
   .WithTags("performance", "orders")
   .Info("Order processing completed");

Non-Fluent Global Methods

The following global configuration methods are not fluent and must be called separately:

// ✅ Global configuration - call separately, not in chains
Log.SetProjectToken("your-project-token");
Log.AddMetaContext("AppVersion", "1.2.3");
Log.Identify(new AuthUser { Id = "123", Email = "user@example.com" });
Log.Disable();
Log.Enable();
Log.Logout();
Log.Reset();

// ✅ Then use fluent syntax for individual logs
Log.WithCorrelationId("req-123")
   .WithMetadata("processingTime", 500)
   .WithContext("operation", "UserLogin")
   .WithTags("authentication", "success")
   .Info("User authenticated successfully");

Important

Global methods like SetProjectToken, AddMetaContext, Identify, Disable, Enable, Logout, and Reset are not chainable. These configure the logger globally and should be called independently, typically during application startup or specific events.

Best Practices

Fluent Syntax Best Practices

  • Chain logically: Group related metadata and context together
  • Use meaningful keys: Make metadata and context keys descriptive
  • Tag consistently: Establish tagging conventions across your application
  • Include relevant timing: Add execution times for performance tracking
  • Combine with correlation IDs: Use correlation IDs for request tracking
  • Don't over-chain: Keep chains readable - break into multiple lines if needed
  • Separate global config: Use global methods independently, not in fluent chains

Common Patterns Summary

// Complete fluent pattern with correlation ID
Log.WithCorrelationId(requestId)
   .WithMetadata("executionTimeMs", elapsed)
   .WithContext("operation", operationName)
   .WithTags("performance", "monitoring")
   .Info("Operation completed");

// Error handling pattern
Log.WithCorrelationId(requestId)
   .WithMetadata("errorCode", ex.ErrorCode)
   .WithMetadata("retryAttempt", 2)
   .WithContext("operation", "PaymentProcessing")
   .WithTags("error", "payment", "critical")
   .Error("Payment failed");

// API request pattern
Log.WithCorrelationId(requestId)
   .WithMetadata("responseTimeMs", responseTime)
   .WithMetadata("statusCode", 200)
   .WithContext("endpoint", endpoint)
   .WithContext("httpMethod", "POST")
   .WithTags("api", "external")
   .Info("API call completed");

// Database operation pattern
Log.WithMetadata("rowsAffected", rows)
   .WithMetadata("executionTimeMs", executionTime)
   .WithContext("sqlQuery", query)
   .WithContext("tableName", "Orders")
   .WithTags("database", "performance")
   .Debug("Query executed");

Next Steps

Previous
Exception Handling