This commit is contained in:
bob
2026-01-28 10:29:49 -06:00
commit 1e90daabb5
157 changed files with 9503 additions and 0 deletions

303
GrafanaBlazor/README.md Normal file
View File

@@ -0,0 +1,303 @@
# Blazor Server App with Grafana Observability Stack
This project provides a complete infrastructure-as-code setup for deploying a Blazor Server application to Azure with comprehensive logging and metrics capabilities for use with Grafana.
## Architecture
The solution includes:
- **Azure App Service** - Hosting the Blazor Server application
- **Application Insights** - Azure-native monitoring and telemetry
- **Log Analytics Workspace** - Centralized logging
- **Prometheus Metrics** - Exposed at `/metrics` endpoint
- **OpenTelemetry** - Distributed tracing support
- **Serilog** - Structured logging
## Project Structure
```
.
├── main.bicep # Main Bicep file (subscription-level)
├── modules/
│ ├── monitoring.bicep # Log Analytics & Application Insights
│ └── appService.bicep # App Service Plan & Web App
├── BlazorApp/ # Blazor Server application
│ ├── Components/
│ │ ├── Layout/
│ │ │ ├── MainLayout.razor
│ │ │ └── NavMenu.razor
│ │ └── Pages/
│ │ ├── Home.razor
│ │ ├── Metrics.razor # Metrics demo page
│ │ └── Logs.razor # Logging demo page
│ ├── Program.cs # App configuration
│ ├── BlazorApp.csproj # Project file with dependencies
│ └── appsettings.json # Configuration
├── deploy.sh # Deployment script
└── README.md # This file
```
## Prerequisites
- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli) installed and configured
- [.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0)
- Azure subscription with appropriate permissions
- [Grafana](https://grafana.com/) instance (can be Azure Managed Grafana or self-hosted)
## Features
### Logging
- **Serilog** for structured logging with console and file outputs
- **Application Insights** integration for Azure-native logging
- Log levels: Information, Warning, Error
- Structured log properties for better querying
### Metrics
- **Prometheus** metrics exposed at `/metrics` endpoint
- **OpenTelemetry** instrumentation for ASP.NET Core and HTTP clients
- Custom metrics tracking (counters, timers)
- Health check endpoint at `/health`
### Demo Pages
- **Home** - Overview and quick log generation
- **Metrics** - Interactive metrics demonstration
- **Logs** - Test different log levels and structured logging
## Deployment
### 1. Deploy Azure Infrastructure
```bash
# Login to Azure
az login
# Run the deployment script
./deploy.sh
```
This will create:
- Resource Group
- App Service Plan (Basic B1 tier)
- Web App (Linux, .NET 8)
- Application Insights
- Log Analytics Workspace
### 2. Build and Deploy the Application
```bash
# Navigate to the app directory
cd BlazorApp
# Restore dependencies
dotnet restore
# Build the application
dotnet build
# Publish the application
dotnet publish -c Release -o ./publish
# Create deployment package
cd publish
zip -r ../app.zip .
cd ..
# Deploy to Azure
az webapp deployment source config-zip \
--resource-group rg-blazor-grafana \
--name <your-webapp-name> \
--src app.zip
```
### 3. Verify Deployment
Once deployed, you can access:
- **Application**: `https://<your-webapp-name>.azurewebsites.net`
- **Metrics**: `https://<your-webapp-name>.azurewebsites.net/metrics`
- **Health Check**: `https://<your-webapp-name>.azurewebsites.net/health`
## Grafana Integration
### Option 1: Prometheus Data Source
1. In Grafana, add a new Prometheus data source
2. Set the URL to: `https://<your-webapp-name>.azurewebsites.net`
3. Configure scrape interval (e.g., 15s)
4. Save and test the connection
### Option 2: Azure Monitor Data Source
1. In Grafana, add an Azure Monitor data source
2. Configure with your Azure subscription details
3. Point to your Application Insights instance
4. You'll have access to:
- Application logs
- Traces
- Metrics
- Dependencies
### Creating Dashboards
**Sample Queries for Prometheus:**
```promql
# Request rate
rate(http_requests_received_total[5m])
# Request duration
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
# Error rate
rate(http_requests_received_total{status_code=~"5.."}[5m])
```
**Sample Queries for Azure Monitor:**
```kusto
// Application logs
traces
| where timestamp > ago(1h)
| project timestamp, message, severityLevel
// Request performance
requests
| where timestamp > ago(1h)
| summarize avg(duration), percentile(duration, 95) by bin(timestamp, 5m)
// Custom events
customEvents
| where timestamp > ago(1h)
| summarize count() by name
```
## Available Metrics
The application exposes the following metrics at `/metrics`:
- `http_requests_received_total` - Total HTTP requests received
- `http_request_duration_seconds` - HTTP request duration histogram
- `http_requests_in_progress` - Current HTTP requests in progress
- `process_cpu_seconds_total` - Process CPU time
- `process_working_set_bytes` - Process memory usage
- `dotnet_*` - Various .NET runtime metrics
## Local Development
```bash
cd BlazorApp
dotnet run
```
Access the app at `https://localhost:5001` or `http://localhost:5000`
## Configuration
### appsettings.json
Configure logging levels and Application Insights:
```json
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning"
}
}
},
"ApplicationInsights": {
"ConnectionString": "your-connection-string"
}
}
```
### Environment Variables
The following environment variables are automatically set in Azure:
- `APPLICATIONINSIGHTS_CONNECTION_STRING`
- `APPINSIGHTS_INSTRUMENTATIONKEY`
- `ASPNETCORE_ENVIRONMENT`
## Customization
### Adding Custom Metrics
```csharp
// In your Razor component
@using Prometheus
private static readonly Counter CustomCounter = Metrics
.CreateCounter("myapp_custom_counter", "Description");
private void MyMethod()
{
CustomCounter.Inc();
}
```
### Adding Custom Logs
```csharp
@inject ILogger<MyComponent> Logger
Logger.LogInformation("User {UserId} performed action {Action}",
userId, actionName);
```
## Monitoring Best Practices
1. **Use structured logging** - Always use parameterized log messages
2. **Set appropriate log levels** - Don't overuse Information level
3. **Add context** - Include relevant properties in logs
4. **Monitor error rates** - Set up alerts in Grafana
5. **Track business metrics** - Not just technical metrics
6. **Use distributed tracing** - Leverage OpenTelemetry spans
## Troubleshooting
### Application Insights not receiving data
- Check the connection string in Azure portal
- Verify Application Insights instrumentation key
- Check network connectivity from App Service
### Prometheus metrics not showing
- Ensure `/metrics` endpoint is accessible
- Check if Prometheus is configured correctly in Grafana
- Verify App Service networking rules
### Logs not appearing
- Check Log Analytics workspace connection
- Verify Serilog configuration
- Check file permissions for log files
## Cost Considerations
This setup uses:
- App Service Plan: Basic B1 (~$55/month)
- Application Insights: Pay-as-you-go (first 5GB free)
- Log Analytics: Pay-as-you-go (first 5GB free)
To reduce costs:
- Use Free tier App Service for testing
- Adjust log retention periods
- Implement sampling in Application Insights
## Clean Up
To delete all resources:
```bash
az group delete --name rg-blazor-grafana --yes --no-wait
```
## Resources
- [Blazor Documentation](https://docs.microsoft.com/aspnet/core/blazor/)
- [Application Insights](https://docs.microsoft.com/azure/azure-monitor/app/app-insights-overview)
- [Prometheus](https://prometheus.io/docs/introduction/overview/)
- [Grafana](https://grafana.com/docs/)
- [OpenTelemetry](https://opentelemetry.io/docs/)
- [Serilog](https://serilog.net/)
## License
This project is provided as-is for educational and demonstration purposes.