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:
- Serilog - Configured in
Program.cs, writes to: - Console (always)
-
File:
{DataPath}/Logs/Server/cesivi-{date}.log(always) -
RequestLoggingMiddleware - HTTP request/response logging:
- Detailed logs to file (always)
- Configurable console output (can be reduced)
Configuration Options¶
1. Microsoft.AspNetCore Logging Levels¶
Controls ASP.NET Core framework logging (Kestrel, routing, etc.)
Location: appsettings.json → Logging → LogLevel
{
"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.json → Cesivi → RequestLogging
{
"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!
Related Documentation¶
- QUICK_START.md - Getting started guide
- DEPLOYMENT_GUIDE.md - Production deployment
- TROUBLESHOOTING.md - Common issues
- ../Scripts/GENERATE_DATA_GUIDE.md - Data generation
Last Updated: 2025-11-20 Version: 1.0