project setup with core files including configuration, package management, and basic structure. Added .gitignore, README, and various TypeScript types for CMS components. Implemented initial components and layouts for the application.
This commit is contained in:
101
middlelayer/plugins/monitoring.ts
Normal file
101
middlelayer/plugins/monitoring.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import type { ApolloServerPlugin } from '@apollo/server';
|
||||
import { logger, logQuery, logError } from '../monitoring/logger.js';
|
||||
import {
|
||||
queryCounter,
|
||||
queryDuration,
|
||||
errorCounter,
|
||||
queryComplexityGauge,
|
||||
} from '../monitoring/metrics.js';
|
||||
import { createTrace, endTrace } from '../monitoring/tracing.js';
|
||||
|
||||
/**
|
||||
* Monitoring Plugin für Apollo Server
|
||||
* Sammelt Logs, Metrics und Traces für jeden Request
|
||||
*/
|
||||
export const monitoringPlugin = (): ApolloServerPlugin => {
|
||||
return {
|
||||
async requestDidStart() {
|
||||
return {
|
||||
async didResolveOperation({ request, operationName }) {
|
||||
// Erstelle Trace für Request
|
||||
const traceId = createTrace().traceId;
|
||||
(request as any).traceId = traceId;
|
||||
|
||||
logger.info('GraphQL operation started', {
|
||||
operationName: operationName || 'unknown',
|
||||
query: request.query,
|
||||
variables: request.variables,
|
||||
traceId,
|
||||
});
|
||||
},
|
||||
|
||||
async willSendResponse({ request, response }) {
|
||||
const traceId = (request as any).traceId;
|
||||
const operationName = request.operationName || 'unknown';
|
||||
const duration = traceId ? endTrace(traceId) : 0;
|
||||
|
||||
// Log Query
|
||||
logQuery(operationName, request.variables, duration);
|
||||
|
||||
// Metrics
|
||||
const status = response.errors && response.errors.length > 0 ? 'error' : 'success';
|
||||
queryCounter.inc({ operation: operationName, status });
|
||||
queryDuration.observe({ operation: operationName }, duration / 1000);
|
||||
|
||||
// Log Errors
|
||||
if (response.errors && response.errors.length > 0) {
|
||||
response.errors.forEach((error) => {
|
||||
logError(error as Error, {
|
||||
operationName,
|
||||
traceId,
|
||||
});
|
||||
errorCounter.inc({
|
||||
type: error.extensions?.code as string || 'UNKNOWN',
|
||||
operation: operationName,
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
async didEncounterErrors({ request, errors }) {
|
||||
const traceId = (request as any).traceId;
|
||||
const operationName = request.operationName || 'unknown';
|
||||
|
||||
errors.forEach((error) => {
|
||||
logError(error as Error, {
|
||||
operationName,
|
||||
traceId,
|
||||
});
|
||||
errorCounter.inc({
|
||||
type: error.extensions?.code as string || 'UNKNOWN',
|
||||
operation: operationName,
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Plugin für Query Complexity Tracking
|
||||
*/
|
||||
export const queryComplexityMonitoringPlugin = (): ApolloServerPlugin => {
|
||||
return {
|
||||
async requestDidStart() {
|
||||
return {
|
||||
async didResolveOperation({ request, operationName }) {
|
||||
// Wird vom queryComplexityPlugin gesetzt
|
||||
const complexity = (request as any).complexity;
|
||||
if (complexity) {
|
||||
queryComplexityGauge.set(
|
||||
{ operation: operationName || 'unknown' },
|
||||
complexity
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user