419 lines
10 KiB
Markdown
419 lines
10 KiB
Markdown
# EonaCat.Logger.LogServer
|
|
|
|
### Server Setup
|
|
|
|
1. **Install SQL Server** (or update connection string for other providers)
|
|
|
|
2. **Update appsettings.json**:
|
|
```json
|
|
{
|
|
"ConnectionStrings": {
|
|
"DefaultConnection": "Server=localhost;Database=LogCentral;Trusted_Connection=True;TrustServerCertificate=True"
|
|
},
|
|
"Logging": {
|
|
"LogLevel": {
|
|
"Default": "Information"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
3. **Run the server**:
|
|
```bash
|
|
dotnet run
|
|
```
|
|
|
|
4. **Create an API Key** (via SQL or admin panel):
|
|
```sql
|
|
INSERT INTO Applications (Name, ApiKey, IsActive, CreatedAt)
|
|
VALUES ('MyApp', NEWID(), 1, GETUTCDATE())
|
|
```
|
|
|
|
### Client Installation
|
|
|
|
#### Via NuGet Package Manager:
|
|
```bash
|
|
dotnet add package EonaCat.Logger.LogClient
|
|
```
|
|
|
|
#### Via Package Manager Console:
|
|
```powershell
|
|
Install-Package EonaCat.Logger.LogClient
|
|
```
|
|
|
|
## 📖 Usage Examples
|
|
|
|
### Basic Setup
|
|
|
|
```csharp
|
|
using EonaCat.Logger.LogClient;
|
|
using EonaCat.Logger.LogClient.Models;
|
|
|
|
// Configure the client
|
|
var options = new LogCentralOptions
|
|
{
|
|
ServerUrl = "https://your-logcentral-server.com",
|
|
ApiKey = "your-api-key-here",
|
|
ApplicationName = "MyAwesomeApp",
|
|
ApplicationVersion = "1.0.0",
|
|
Environment = "Production",
|
|
BatchSize = 50,
|
|
FlushIntervalSeconds = 5
|
|
};
|
|
|
|
var logClient = new LogCentralClient(options);
|
|
```
|
|
|
|
### Integration with EonaCat.Logger
|
|
|
|
```csharp
|
|
using EonaCat.Logger;
|
|
using EonaCat.Logger.LogClient.Integration;
|
|
|
|
var loggerSettings = new LoggerSettings();
|
|
loggerSettings.UseLocalTime = true;
|
|
loggerSettings.Id = "TEST";
|
|
var logger = new LogManager(loggerSettings);
|
|
|
|
// Create the adapter
|
|
var adapter = new LogCentralEonaCatAdapter(loggerSettings, logClient);
|
|
|
|
// Now all EonaCat.Logger logs will be sent to LogCentral automatically
|
|
logger.Log("Application started", LogLevel.Info);
|
|
logger.Log("User logged in", LogLevel.Info, "Authentication");
|
|
```
|
|
|
|
### Manual Logging
|
|
|
|
```csharp
|
|
// Simple log
|
|
await logClient.LogAsync(new LogEntry
|
|
{
|
|
Level = LogLevel.Information,
|
|
Category = "Startup",
|
|
Message = "Application started successfully"
|
|
});
|
|
|
|
// Log with properties
|
|
await logClient.LogAsync(new LogEntry
|
|
{
|
|
Level = LogLevel.Information,
|
|
Category = "UserAction",
|
|
Message = "User performed action",
|
|
UserId = "user123",
|
|
Properties = new Dictionary<string, object>
|
|
{
|
|
["Action"] = "Purchase",
|
|
["Amount"] = 99.99,
|
|
["ProductId"] = "prod-456"
|
|
}
|
|
});
|
|
|
|
// Log exception
|
|
try
|
|
{
|
|
// Your code
|
|
throw new Exception("Something went wrong");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await logClient.LogExceptionAsync(ex, "Error processing order",
|
|
new Dictionary<string, object>
|
|
{
|
|
["OrderId"] = "12345",
|
|
["CustomerId"] = "cust-789"
|
|
});
|
|
}
|
|
```
|
|
|
|
### Security Event Logging
|
|
|
|
```csharp
|
|
await logClient.LogSecurityEventAsync(
|
|
"LoginAttempt",
|
|
"Failed login attempt detected",
|
|
new Dictionary<string, object>
|
|
{
|
|
["Username"] = "admin",
|
|
["IPAddress"] = "192.168.1.100",
|
|
["Attempts"] = 5
|
|
}
|
|
);
|
|
|
|
await logClient.LogSecurityEventAsync(
|
|
"UnauthorizedAccess",
|
|
"Unauthorized API access attempt",
|
|
new Dictionary<string, object>
|
|
{
|
|
["Endpoint"] = "/api/admin/users",
|
|
["Method"] = "DELETE",
|
|
["UserId"] = "user456"
|
|
}
|
|
);
|
|
```
|
|
|
|
### Analytics Logging
|
|
|
|
```csharp
|
|
// Track user events
|
|
await logClient.LogAnalyticsAsync("PageView",
|
|
new Dictionary<string, object>
|
|
{
|
|
["Page"] = "/products/electronics",
|
|
["Duration"] = 45.2,
|
|
["Source"] = "Google"
|
|
}
|
|
);
|
|
|
|
await logClient.LogAnalyticsAsync("Purchase",
|
|
new Dictionary<string, object>
|
|
{
|
|
["ProductId"] = "prod-123",
|
|
["Price"] = 299.99,
|
|
["Category"] = "Electronics",
|
|
["PaymentMethod"] = "CreditCard"
|
|
}
|
|
);
|
|
|
|
await logClient.LogAnalyticsAsync("FeatureUsage",
|
|
new Dictionary<string, object>
|
|
{
|
|
["Feature"] = "DarkMode",
|
|
["Enabled"] = true,
|
|
["Platform"] = "iOS"
|
|
}
|
|
);
|
|
```
|
|
|
|
### ASP.NET Core Integration
|
|
|
|
```csharp
|
|
// Program.cs or Startup.cs
|
|
public class Program
|
|
{
|
|
public static void Main(string[] args)
|
|
{
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
// Register LogCentral
|
|
var logCentralOptions = new LogCentralOptions
|
|
{
|
|
ServerUrl = builder.Configuration["LogCentral:ServerUrl"],
|
|
ApiKey = builder.Configuration["LogCentral:ApiKey"],
|
|
ApplicationName = "MyWebApp",
|
|
ApplicationVersion = "1.0.0",
|
|
Environment = builder.Environment.EnvironmentName
|
|
};
|
|
|
|
var logClient = new LogCentralClient(logCentralOptions);
|
|
builder.Services.AddSingleton(logClient);
|
|
|
|
var app = builder.Build();
|
|
|
|
// Use middleware to log requests
|
|
app.Use(async (context, next) =>
|
|
{
|
|
var requestId = Guid.NewGuid().ToString();
|
|
|
|
await logClient.LogAsync(new LogEntry
|
|
{
|
|
Level = LogLevel.Information,
|
|
Category = "HTTP",
|
|
Message = $"{context.Request.Method} {context.Request.Path}",
|
|
RequestId = requestId,
|
|
Properties = new Dictionary<string, object>
|
|
{
|
|
["Method"] = context.Request.Method,
|
|
["Path"] = context.Request.Path.Value,
|
|
["QueryString"] = context.Request.QueryString.Value
|
|
}
|
|
});
|
|
|
|
await next();
|
|
});
|
|
|
|
app.Run();
|
|
}
|
|
}
|
|
```
|
|
|
|
### Windows Service / Console App
|
|
|
|
```csharp
|
|
using EonaCat.Logger.LogClient;
|
|
using Microsoft.Extensions.Hosting;
|
|
|
|
public class Worker : BackgroundService
|
|
{
|
|
private readonly LogCentralClient _logClient;
|
|
|
|
public Worker(LogCentralClient logClient)
|
|
{
|
|
_logClient = logClient;
|
|
}
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
await _logClient.LogAsync(new LogEntry
|
|
{
|
|
Level = LogLevel.Information,
|
|
Category = "Service",
|
|
Message = "Worker service started"
|
|
});
|
|
|
|
while (!stoppingToken.IsCancellationRequested)
|
|
{
|
|
try
|
|
{
|
|
// Your work here
|
|
await Task.Delay(1000, stoppingToken);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await _logClient.LogExceptionAsync(ex, "Error in worker");
|
|
}
|
|
}
|
|
|
|
await _logClient.FlushAndDisposeAsync();
|
|
}
|
|
}
|
|
```
|
|
|
|
### WPF / WinForms Application
|
|
|
|
```csharp
|
|
public partial class MainWindow : Window
|
|
{
|
|
private readonly LogCentralClient _logClient;
|
|
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
|
|
_logClient = new LogCentralClient(new LogCentralOptions
|
|
{
|
|
ServerUrl = "https://logs.mycompany.com",
|
|
ApiKey = "your-api-key",
|
|
ApplicationName = "MyDesktopApp",
|
|
ApplicationVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(),
|
|
Environment = "Production"
|
|
});
|
|
|
|
Application.Current.DispatcherUnhandledException += OnUnhandledException;
|
|
}
|
|
|
|
private async void OnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
|
|
{
|
|
await _logClient.LogExceptionAsync(e.Exception, "Unhandled exception in UI");
|
|
e.Handled = true;
|
|
}
|
|
|
|
protected override async void OnClosing(CancelEventArgs e)
|
|
{
|
|
await _logClient.FlushAndDisposeAsync();
|
|
base.OnClosing(e);
|
|
}
|
|
}
|
|
```
|
|
|
|
## 🎯 Advanced Features
|
|
|
|
### Correlation IDs for Distributed Tracing
|
|
|
|
```csharp
|
|
var correlationId = Guid.NewGuid().ToString();
|
|
|
|
await logClient.LogAsync(new LogEntry
|
|
{
|
|
Level = LogLevel.Information,
|
|
Category = "OrderProcessing",
|
|
Message = "Order created",
|
|
CorrelationId = correlationId,
|
|
Properties = new Dictionary<string, object> { ["OrderId"] = "12345" }
|
|
});
|
|
|
|
// In another service
|
|
await logClient.LogAsync(new LogEntry
|
|
{
|
|
Level = LogLevel.Information,
|
|
Category = "PaymentProcessing",
|
|
Message = "Payment processed",
|
|
CorrelationId = correlationId, // Same ID
|
|
Properties = new Dictionary<string, object> { ["Amount"] = 99.99 }
|
|
});
|
|
```
|
|
|
|
### Performance Monitoring
|
|
|
|
```csharp
|
|
var stopwatch = Stopwatch.StartNew();
|
|
|
|
try
|
|
{
|
|
// Your operation
|
|
await SomeSlowOperation();
|
|
}
|
|
finally
|
|
{
|
|
stopwatch.Stop();
|
|
|
|
await logClient.LogAsync(new LogEntry
|
|
{
|
|
Level = LogLevel.Information,
|
|
Category = "Performance",
|
|
Message = "Operation completed",
|
|
Properties = new Dictionary<string, object>
|
|
{
|
|
["Operation"] = "DatabaseQuery",
|
|
["DurationMs"] = stopwatch.ElapsedMilliseconds,
|
|
["Status"] = "Success"
|
|
}
|
|
});
|
|
}
|
|
```
|
|
|
|
## 📊 Dashboard Features
|
|
|
|
- **Real-time monitoring**: Auto-refreshes every 30 seconds
|
|
- **Advanced search**: Full-text search across all log fields
|
|
- **Filtering**: By application, environment, level, date range
|
|
- **Charts**: Visual representation of log levels and trends
|
|
- **Export**: Download logs as CSV or JSON
|
|
- **Alerts**: Configure notifications for critical events (planned)
|
|
|
|
## 🔒 Security Best Practices
|
|
|
|
1. **Use HTTPS** for production deployments
|
|
2. **Rotate API keys** regularly
|
|
3. **Limit API key permissions** by application
|
|
4. **Store API keys** in secure configuration (Azure Key Vault, AWS Secrets Manager)
|
|
5. **Enable authentication** for dashboard access (add authentication middleware)
|
|
|
|
## 🚀 Deployment
|
|
|
|
### Docker Deployment
|
|
|
|
```dockerfile
|
|
FROM mcr.microsoft.com/dotnet/aspnet:8.0
|
|
WORKDIR /app
|
|
COPY --from=build /app/publish .
|
|
ENTRYPOINT ["dotnet", "LogCentral.Server.dll"]
|
|
```
|
|
|
|
### Azure Deployment
|
|
|
|
```bash
|
|
az webapp create --resource-group MyResourceGroup --plan MyPlan --name logcentral --runtime "DOTNETCORE:8.0"
|
|
az webapp deployment source config-zip --resource-group MyResourceGroup --name logcentral --src logcentral.zip
|
|
```
|
|
|
|
## 📈 Scalability
|
|
|
|
For high-volume applications:
|
|
|
|
1. Use **Redis** for caching
|
|
2. Implement **Elasticsearch** for faster searches
|
|
3. Use **message queues** (RabbitMQ, Azure Service Bus) for async processing
|
|
4. Partition database by date ranges
|
|
5. Implement log archival and retention policies
|