contextual_shelf 0.1.0
contextual_shelf: ^0.1.0 copied to clipboard
shelf using contextual logger
Contextual Shelf #
A powerful logging middleware for Shelf applications that provides structured, configurable logging through integration with the contextual logging package.
Features #
- π Structured Logging: Multiple output channels with different formatters
- β±οΈ Performance Monitoring: Request/response timing and memory usage tracking
- π Security: Sensitive data sanitization and header filtering
- π― Configurable: Custom request filtering and log profiles
- π¨ Multiple Formats: Support for JSON, pretty-printed, and plain text output
- π Error Handling: Comprehensive error tracking and reporting
Installation #
Add this to your package's pubspec.yaml
file:
dependencies:
contextual_shelf: ^1.0.0
Usage #
Basic Setup #
import 'package:contextual/contextual.dart';
import 'package:contextual_shelf/contextual_shelf.dart';
import 'package:shelf/shelf.dart' as shelf;
void main() async {
// Create a logger with console and file output
final logger = Logger()
..addChannel(
'console',
ConsoleLogDriver(),
formatter: PrettyLogFormatter(),
)
..addChannel(
'file',
DailyFileLogDriver('logs/server.log'),
formatter: JsonLogFormatter(),
);
// Set up the logging middleware
final logWriter = DefaultLogWriter(
logger,
sanitizer: Sanitizer(mask: '[REDACTED]'),
);
final logProfile = LogNonGetRequests();
final httpLogger = HttpLogger(logProfile, logWriter);
// Add the middleware to your Shelf pipeline
final handler = const shelf.Pipeline()
.addMiddleware(httpLogger.middleware)
.addHandler(myHandler);
await shelf.serve(handler, 'localhost', 8080);
}
Custom Request Filtering #
Create a custom log profile to control which requests are logged:
class ApiLogProfile implements LogProfile {
@override
bool shouldLogRequest(shelf.Request request) {
return request.method != 'GET' || request.url.path.startsWith('api/');
}
}
Sensitive Data Handling #
Configure the sanitizer to mask sensitive information:
final logWriter = DefaultLogWriter(
logger,
sanitizer: Sanitizer(
mask: '[REDACTED]',
),
);
Log Output Examples #
Pretty-Printed Console Output
[2024-02-15 10:30:45.123] [INFO] POST /api/users [200] 45ms
[2024-02-15 10:30:46.456] [ERROR] GET /api/data [500] 123ms | Error: Database connection failed
JSON File Output
{
"timestamp": "2024-02-15T10:30:45.123Z",
"level": "INFO",
"method": "POST",
"path": "/api/users",
"status": 200,
"duration_ms": 45,
"headers": {
"content-type": "application/json",
"authorization": "[REDACTED]"
}
}
Advanced Usage #
Multiple Output Channels #
Configure different formatters for different outputs:
final logger = Logger()
..addChannel(
'console',
ConsoleLogDriver(),
formatter: PrettyLogFormatter(),
)
..addChannel(
'file',
DailyFileLogDriver('logs/app.log'),
formatter: JsonLogFormatter(),
)
..addChannel(
'metrics',
WebhookLogDriver(Uri.parse('https://metrics.example.com')),
formatter: PlainTextLogFormatter(),
);
Error Handling #
The middleware automatically catches and logs errors:
Future<shelf.Response> handler(shelf.Request request) async {
try {
// Your handler code
} catch (e, stack) {
// Error will be logged with full context
return shelf.Response.internalServerError();
}
}
Performance Monitoring #
Each log entry includes:
- Request duration
- Memory usage
- Process ID
- Timestamp
API Reference #
Key Components #
HttpLogger
: Main middleware class for Shelf integrationLogWriter
: Interface for writing log entriesLogProfile
: Interface for request filteringSanitizer
: Utility for cleaning sensitive dataDefaultLogWriter
: Standard implementation of LogWriter
Built-in Log Profiles #
LogNonGetRequests
: Logs all non-GET requestsApiLogProfile
: Example profile for API request logging
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
License #
This project is licensed under the MIT License - see the LICENSE file for details.