Skip to content

Cesivi Server - Logging Configuration Guide

This guide explains how to configure logging in Cesivi Server to reduce verbose console output while maintaining visibility of important information.

Quick Answer: Reduce Console Logging

To see only request summaries (URL + status + duration) without headers/bodies:

Edit appsettings.Development.json (or appsettings.json):

{
  "Cesivi": {
    "RequestLogging": {
      "LogHeaders": false,
      "LogRequestBody": false,
      "LogResponseBody": false,
      "LogToConsole": true,
      "SummaryFormat": "{Method} {Path} => {StatusCode} ({Duration}ms) | {Count}"
    }
  }
}

Result: You'll see concise logs like:

GET /sites/basic/_api/web => 200 (15ms) | 1 object
POST /sites/basic/_api/web/lists => 201 (42ms)
GET /sites/basic/_api/web/lists('guid')/items => 200 (28ms) | 10 items


Logging Architecture

Cesivi Server uses two logging systems:

  1. Serilog - Configured in Program.cs, writes to:
  2. Console (always)
  3. File: {DataPath}/Logs/Server/cesivi-{date}.log (always)

  4. RequestLoggingMiddleware - HTTP request/response logging:

  5. Detailed logs to file (always)
  6. Configurable console output (can be reduced)

Configuration Options

1. Microsoft.AspNetCore Logging Levels

Controls ASP.NET Core framework logging (Kestrel, routing, etc.)

Location: appsettings.jsonLoggingLogLevel

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"  // Change to "Information" for more detail
    }
  }
}

Levels: - Trace - Very detailed (diagnostic) - Debug - Debugging information - Information - General informational messages - Warning - Warning messages only - Error - Errors only - Critical - Critical errors only - None - No logging

2. Request Logging Configuration

Controls HTTP request/response logging detail.

Location: appsettings.jsonCesiviRequestLogging

{
  "Cesivi": {
    "RequestLogging": {
      "LogHeaders": false,           // Log HTTP headers
      "LogRequestBody": false,       // Log request body (XML/JSON)
      "LogResponseBody": false,      // Log response body
      "LogToConsole": true,          // Enable console logging
      "SummaryFormat": "{Method} {Path} => {StatusCode} ({Duration}ms) | {Count}"
    }
  }
}

Available Format Tokens: - {Method} - HTTP method (GET, POST, etc.) - {Path} - Request path - {StatusCode} - HTTP status code (200, 404, etc.) - {Duration} - Request duration in milliseconds - {Count} - Number of items returned (if collection)

Note: Currently, the RequestLogging section needs to be manually added to configuration files. Full support with automatic count detection is planned for a future update.

3. Serilog Configuration

Controls file-based logging detail.

Location: Program.cs (requires code change)

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()  // Change to Information, Warning, etc.
    .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
    .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
    .Enrich.FromLogContext()
    .WriteTo.Console()  // Remove this line to disable console output
    .WriteTo.File(
        Path.Combine(logPath, "cesivi-.log"),
        rollingInterval: RollingInterval.Day,
        outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
    )
    .CreateLogger();

Common Scenarios

Scenario 1: Development (Maximum Detail)

Use Case: Debugging issues, understanding request flow

Configuration:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "Microsoft.AspNetCore": "Information"
    }
  },
  "Cesivi": {
    "RequestLogging": {
      "LogHeaders": true,
      "LogRequestBody": true,
      "LogResponseBody": true,
      "LogToConsole": true
    }
  }
}

Result: Full request/response details in console and file


Scenario 2: Clean Console (Minimal)

Use Case: Normal development, reduce console clutter

Configuration:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Cesivi": {
    "RequestLogging": {
      "LogHeaders": false,
      "LogRequestBody": false,
      "LogResponseBody": false,
      "LogToConsole": true,
      "SummaryFormat": "{Method} {Path} => {StatusCode} ({Duration}ms)"
    }
  }
}

Result: - Console: One-line summary per request - File: Full details still logged


Scenario 3: Production (Minimal Console, Full File)

Use Case: Production deployment, keep console clean but log everything to file

Configuration:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Cesivi": {
    "RequestLogging": {
      "LogHeaders": false,
      "LogRequestBody": false,
      "LogResponseBody": false,
      "LogToConsole": true,
      "SummaryFormat": "{Method} {Path} => {StatusCode}"
    }
  }
}

Result: - Console: Minimal summary (method + path + status) - File: Full request/response details


Scenario 4: Silent Console (File Only)

Use Case: Automated testing, CI/CD pipelines

Configuration:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning",
      "Microsoft.AspNetCore": "Error"
    }
  },
  "Cesivi": {
    "RequestLogging": {
      "LogHeaders": false,
      "LogRequestBody": false,
      "LogResponseBody": false,
      "LogToConsole": false
    }
  }
}

Result: - Console: Errors/warnings only - File: Full details still logged


Environment-Specific Configuration

Use environment-specific configuration files:

appsettings.json                # Base configuration
appsettings.Development.json    # Development overrides
appsettings.Production.json     # Production overrides
appsettings.Test.json           # Testing overrides

Set environment:

# PowerShell
$env:ASPNETCORE_ENVIRONMENT = "Development"
dotnet run

# Or use launchSettings.json (Visual Studio / VS Code)


Current Logging Behavior

As of 2025-11-20:

What's Always Logged (Console + File):

  • Request ID (8-character GUID)
  • Timestamp
  • HTTP method + path
  • Status code
  • Duration

What's Configurable (via appsettings):

  • Microsoft.AspNetCore log level
  • Cesivi log level

What Requires Code Changes:

  • Request headers logging
  • Request body logging
  • Response body logging
  • Custom summary format

Planned Enhancement: The RequestLogging configuration section shown above is the proposed design. Full implementation is pending.


Log File Locations

Environment Default Path
Development ./MockData/Logs/Server/cesivi-{date}.log
Production ./MockData/Logs/Server/cesivi-{date}.log
Docker /app/MockData/Logs/Server/cesivi-{date}.log
Custom Set via CESIVI_LOG_PATH environment variable

Log file format:

2025-11-20 14:32:15.123 +00:00 [INF] [12ab34cd] GET /sites/basic/_api/web => 200 (15ms)

Log file features: - Rolling daily files (one file per day) - UTF-8 encoding - Structured format (timestamp, level, message) - Exception stack traces


Understanding Request Logs

Console Output (Current)

========== REQUEST 12ab34cd ==========
Timestamp: 2025-11-20 14:32:15.123 UTC
Method: GET
Path: /sites/basic/_api/web
QueryString:
ContentType:
ContentLength:

Headers:
  Accept: application/json;odata=verbose
  User-Agent: CSOM/16.0
  ...

---------- RESPONSE 12ab34cd ----------
StatusCode: 200
Duration: 15ms
ContentType: application/json;odata=verbose

Response Headers:
  Content-Type: application/json;odata=verbose
  ...

Response Body (2048 chars):
{"d":{"__metadata":{"type":"SP.Web"},"Title":"Basic Test Site",...}}

========== END 12ab34cd ==========

Proposed Minimal Output

[12ab34cd] GET /sites/basic/_api/web => 200 (15ms)

Tips & Best Practices

1. Use Environment Variables for Quick Changes

# Reduce logging temporarily without editing config
$env:Logging__LogLevel__Default = "Warning"
dotnet run

2. Monitor Log File Size

Log files can grow large with verbose logging. Use rolling files (default: daily) and implement cleanup:

# Delete logs older than 7 days
Get-ChildItem "./MockData/Logs/Server" -Filter "*.log" |
    Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-7) } |
    Remove-Item

3. Use Correlation IDs for Debugging

Cesivi Server supports client-provided request IDs via X-Request-Id header:

using (var client = new HttpClient())
{
    var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:5000/sites/basic/_api/web");
    request.Headers.Add("X-Request-Id", "my-custom-id-1234");
    var response = await client.SendAsync(request);
}

Console output will show:

========== REQUEST my-custom-id-1234 (CLIENT CORRELATION) ==========

4. Combine with Tools

Use log analysis tools for large log files:

# Find all 500 errors
Select-String -Path "./MockData/Logs/Server/*.log" -Pattern "StatusCode: 500"

# Find requests slower than 100ms
Select-String -Path "./MockData/Logs/Server/*.log" -Pattern "Duration: [1-9][0-9]{2,}ms"

# Count requests by endpoint
Select-String -Path "./MockData/Logs/Server/*.log" -Pattern "Path: " |
    ForEach-Object { ($_ -split "Path: ")[1] } |
    Group-Object |
    Sort-Object Count -Descending

Roadmap

Planned Enhancements: 1. Full RequestLogging configuration support in middleware 2. Automatic response count detection (e.g., "10 items returned") 3. Structured logging (JSON format option) 4. Performance metrics logging (slow query detection) 5. Request filtering (exclude health checks, static files) 6. Log level overrides per endpoint pattern

Contribute: - Feature requests: GitHub Issues - Pull requests welcome!



Last Updated: 2025-11-20 Version: 1.0