Add Legal Office seal and complete Azure CDN deployment
- Add Legal Office of the Master seal (SVG design with Maltese Cross, scales of justice, legal scroll) - Create legal-office-manifest-template.json for Legal Office credentials - Update SEAL_MAPPING.md and DESIGN_GUIDE.md with Legal Office seal documentation - Complete Azure CDN infrastructure deployment: - Resource group, storage account, and container created - 17 PNG seal files uploaded to Azure Blob Storage - All manifest templates updated with Azure URLs - Configuration files generated (azure-cdn-config.env) - Add comprehensive Azure CDN setup scripts and documentation - Fix manifest URL generation to prevent double slashes - Verify all seals accessible via HTTPS
This commit is contained in:
150
packages/monitoring/src/entra-metrics.ts
Normal file
150
packages/monitoring/src/entra-metrics.ts
Normal file
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* Microsoft Entra VerifiedID metrics
|
||||
* Tracks Entra VerifiedID API usage, success rates, and performance
|
||||
*/
|
||||
|
||||
import { Counter, Histogram, Gauge, register } from 'prom-client';
|
||||
|
||||
// Entra API request metrics
|
||||
export const entraApiRequests = new Counter({
|
||||
name: 'entra_api_requests_total',
|
||||
help: 'Total number of Entra VerifiedID API requests',
|
||||
labelNames: ['operation', 'status'],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
export const entraApiRequestDuration = new Histogram({
|
||||
name: 'entra_api_request_duration_seconds',
|
||||
help: 'Duration of Entra VerifiedID API requests',
|
||||
labelNames: ['operation'],
|
||||
buckets: [0.1, 0.5, 1, 2, 5, 10, 30],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
export const entraApiErrors = new Counter({
|
||||
name: 'entra_api_errors_total',
|
||||
help: 'Total number of Entra VerifiedID API errors',
|
||||
labelNames: ['operation', 'error_type', 'status_code'],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
// Credential issuance metrics
|
||||
export const entraCredentialsIssued = new Counter({
|
||||
name: 'entra_credentials_issued_total',
|
||||
help: 'Total number of credentials issued via Entra VerifiedID',
|
||||
labelNames: ['manifest_name', 'status'],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
export const entraIssuanceDuration = new Histogram({
|
||||
name: 'entra_issuance_duration_seconds',
|
||||
help: 'Time to issue a credential via Entra VerifiedID',
|
||||
labelNames: ['manifest_name'],
|
||||
buckets: [0.5, 1, 2, 5, 10, 30, 60],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
export const entraIssuanceRetries = new Counter({
|
||||
name: 'entra_issuance_retries_total',
|
||||
help: 'Total number of retries for Entra credential issuance',
|
||||
labelNames: ['manifest_name', 'attempt'],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
// Credential verification metrics
|
||||
export const entraCredentialsVerified = new Counter({
|
||||
name: 'entra_credentials_verified_total',
|
||||
help: 'Total number of credentials verified via Entra VerifiedID',
|
||||
labelNames: ['result'],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
export const entraVerificationDuration = new Histogram({
|
||||
name: 'entra_verification_duration_seconds',
|
||||
help: 'Time to verify a credential via Entra VerifiedID',
|
||||
buckets: [0.1, 0.5, 1, 2, 5],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
// Status check metrics
|
||||
export const entraStatusChecks = new Counter({
|
||||
name: 'entra_status_checks_total',
|
||||
help: 'Total number of Entra issuance status checks',
|
||||
labelNames: ['state'],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
export const entraStatusCheckDuration = new Histogram({
|
||||
name: 'entra_status_check_duration_seconds',
|
||||
help: 'Time to check Entra issuance status',
|
||||
buckets: [0.1, 0.5, 1, 2, 5],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
// Token management metrics
|
||||
export const entraTokenRefreshes = new Counter({
|
||||
name: 'entra_token_refreshes_total',
|
||||
help: 'Total number of Entra access token refreshes',
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
export const entraTokenCacheHits = new Counter({
|
||||
name: 'entra_token_cache_hits_total',
|
||||
help: 'Total number of Entra token cache hits',
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
export const entraTokenCacheMisses = new Counter({
|
||||
name: 'entra_token_cache_misses_total',
|
||||
help: 'Total number of Entra token cache misses',
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
// Webhook/callback metrics
|
||||
export const entraWebhooksReceived = new Counter({
|
||||
name: 'entra_webhooks_received_total',
|
||||
help: 'Total number of Entra webhooks received',
|
||||
labelNames: ['event_type', 'status'],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
export const entraWebhookProcessingDuration = new Histogram({
|
||||
name: 'entra_webhook_processing_duration_seconds',
|
||||
help: 'Time to process an Entra webhook',
|
||||
labelNames: ['event_type'],
|
||||
buckets: [0.1, 0.5, 1, 2, 5],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
export const entraWebhookErrors = new Counter({
|
||||
name: 'entra_webhook_errors_total',
|
||||
help: 'Total number of Entra webhook processing errors',
|
||||
labelNames: ['event_type', 'error_type'],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
// Active requests gauge
|
||||
export const entraActiveRequests = new Gauge({
|
||||
name: 'entra_active_requests',
|
||||
help: 'Number of active Entra API requests',
|
||||
labelNames: ['operation'],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
// Success rate calculation helpers
|
||||
// Note: This is a helper function - actual success rate should be calculated
|
||||
// from Prometheus queries like:
|
||||
// rate(entra_credentials_issued_total{status="success"}[5m]) / rate(entra_credentials_issued_total[5m])
|
||||
export function getEntraIssuanceSuccessRate(): number {
|
||||
// This function is a placeholder - actual calculation should be done via Prometheus queries
|
||||
// as prom-client doesn't expose internal metrics directly
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Entra metrics in Prometheus format
|
||||
*/
|
||||
export async function getEntraMetrics(): Promise<string> {
|
||||
return register.metrics();
|
||||
}
|
||||
|
||||
@@ -5,4 +5,11 @@
|
||||
export * from './otel';
|
||||
export * from './metrics';
|
||||
export * from './business-metrics';
|
||||
export * from './entra-metrics';
|
||||
|
||||
// Re-export business metrics with explicit names to avoid conflicts
|
||||
export {
|
||||
documentsProcessed,
|
||||
paymentsProcessed,
|
||||
} from './business-metrics';
|
||||
|
||||
|
||||
@@ -35,21 +35,7 @@ export const dbConnectionsActive = new Gauge({
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
// Business metrics
|
||||
export const documentsProcessed = new Counter({
|
||||
name: 'documents_processed_total',
|
||||
help: 'Total number of documents processed',
|
||||
labelNames: ['status', 'classification'],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
export const paymentsProcessed = new Counter({
|
||||
name: 'payments_processed_total',
|
||||
help: 'Total number of payments processed',
|
||||
labelNames: ['status', 'currency'],
|
||||
registers: [register],
|
||||
});
|
||||
|
||||
// Verifiable credentials metrics
|
||||
export const vcIssued = new Counter({
|
||||
name: 'verifiable_credentials_issued_total',
|
||||
help: 'Total number of verifiable credentials issued',
|
||||
|
||||
Reference in New Issue
Block a user