Added trace in conf
MODIFY
docker/config-standalone.json
docker/config-standalone.json
}
]
},
- "Logging": {
- "logLevel": "D",
- "trace": true,
- "moduleDetails": {
- "ChargingStation": {
- "logLevel": "DEFAULT"
+ "Trace": {
+ "traceIngressHttp": false,
+ "traceEgressHttp": false,
+ "traceOcpp": false,
+ "traceDatabase": false,
+ "traceNotification": false
},
- "Authorizations": {
- "logLevel": "DEFAULT"
- }
- }
+ "Logging": {
+ "logLevel": "D"
}
}

MODIFY
docker/config.json
docker/config.json
}
]
},
- "Logging": {
- "logLevel": "D",
- "trace": true,
- "moduleDetails": {
- "ChargingStation": {
- "logLevel": "DEFAULT"
+ "Trace": {
+ "traceIngressHttp": false,
+ "traceEgressHttp": false,
+ "traceOcpp": false,
+ "traceDatabase": false,
+ "traceNotification": false
},
- "Authorizations": {
- "logLevel": "DEFAULT"
- }
- }
+ "Logging": {
+ "logLevel": "D"
}
}

MODIFY
src/assets/config-template-http.json
src/assets/config-template-http.json
}
]
},
- "Logging": {
- "logLevel": "D",
- "trace": false,
- "moduleDetails": {
- "ChargingStation": {
- "logLevel": "DEFAULT"
+ "Trace": {
+ "traceIngressHttp": false,
+ "traceEgressHttp": false,
+ "traceOcpp": false,
+ "traceDatabase": false,
+ "traceNotification": false
},
- "Authorizations": {
- "logLevel": "DEFAULT"
- }
- }
+ "Logging": {
+ "logLevel": "D"
}
}

MODIFY
src/assets/config-template-https.json
src/assets/config-template-https.json
}
]
},
- "Logging": {
- "logLevel": "D",
- "trace": false,
- "moduleDetails": {
- "ChargingStation": {
- "logLevel": "DEFAULT"
+ "Trace": {
+ "traceIngressHttp": false,
+ "traceEgressHttp": false,
+ "traceOcpp": false,
+ "traceDatabase": false,
+ "traceNotification": false
},
- "Authorizations": {
- "logLevel": "DEFAULT"
- }
- }
+ "Logging": {
+ "logLevel": "D"
}
}

MODIFY
src/assets/configs-aws
src/assets/configs-aws
-Subproject commit c55fdc1c41b17dd4a44044f31f00100bbc0f242b
+Subproject commit f156349b63d5af114ef3ef8428834eda35778864

MODIFY
src/assets/schemas/configuration/configuration.json
src/assets/schemas/configuration/configuration.json
"tasks"
]
},
+ "Trace": {
+ "type": "object",
+ "properties": {
+ "traceIngressHttp": {
+ "type": "boolean"
+ },
+ "traceEgressHttp": {
+ "type": "boolean"
+ },
+ "traceOcpp": {
+ "type": "boolean"
+ },
+ "traceDatabase": {
+ "type": "boolean"
+ },
+ "traceNotification": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "traceIngressHttp",
+ "traceEgressHttp",
+ "traceOcpp",
+ "traceDatabase",
+ "traceNotification"
+ ]
+ },
"Logging": {
"type": "object",
"properties": {
"logLevel": {
"type": "string",
"enum": ["NONE", "D", "I", "W", "E"]
- },
- "trace": {
- "type": "boolean"
- },
- "moduleDetails": {
- "type": "object"
}
},
"required": [
- "logLevel",
- "trace"
+ "logLevel"
]
}
}

MODIFY
src/scheduler/SchedulerManager.ts
src/scheduler/SchedulerManager.ts
@@ -163,6 +163,10 @@ export default class SchedulerManager {
}
private static runTask(task: SchedulerTask, taskConfiguration: SchedulerTaskConfiguration): void {
+ // Set default config
+ if (!taskConfiguration.config) {
+ taskConfiguration.config = {};
+ }
// Do not wait for the task result
void task.run(taskConfiguration.name, taskConfiguration.config);
}

MODIFY
src/storage/mongodb/validator/ConfigurationValidatorStorage.ts
src/storage/mongodb/validator/ConfigurationValidatorStorage.ts
@@ -6,18 +6,17 @@ import global from '../../../types/GlobalType';
export default class ConfigurationValidatorStorage extends SchemaValidator {
private static instance: ConfigurationValidatorStorage | null = null;
- private configuration: Schema;
+ private configuration: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/schemas/configuration/configuration.json`, 'utf8'));
private constructor() {
super('ConfigurationValidatorStorage', {
- strict: false, // When 'true', it fails with anyOf required fields: https://github.com/ajv-validator/ajv/issues/1571
+ strict: true,
allErrors: true,
- removeAdditional: true, // 'all' fails with anyOf documents: Manually added 'additionalProperties: false' in schema due filtering of data in anyOf/oneOf/allOf array (it's standard): https://github.com/ajv-validator/ajv/issues/1784
+ removeAdditional: 'all',
allowUnionTypes: true,
coerceTypes: true,
verbose: true,
});
- this.configuration = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/schemas/configuration/configuration.json`, 'utf8'));
}
public static getInstance(): ConfigurationValidatorStorage {

MODIFY
src/types/configuration/Configuration.ts
src/types/configuration/Configuration.ts
@@ -24,6 +24,7 @@ import OICPEndpointConfiguration from './OICPEndpointConfiguration';
import OICPServiceConfiguration from './OICPServiceConfiguration';
import SchedulerConfiguration from './SchedulerConfiguration';
import StorageConfiguration from './StorageConfiguration';
+import TraceConfiguration from './TraceConfiguration';
import WSDLEndpointConfiguration from './WSDLEndpointConfiguration';
export interface Configuration {
@@ -53,7 +54,8 @@ export interface Configuration {
Migration?: MigrationConfiguration;
EVDatabase?: EVDatabaseConfiguration;
ChargingStationTemplates?: ChargingStationTemplatesConfiguration;
- Axios?: AxiosConfiguration
+ Axios?: AxiosConfiguration;
+ Trace?: TraceConfiguration;
}
export type ConfigurationSection = CryptoConfiguration|CentralSystemServerConfiguration|CentralSystemConfiguration|CentralSystemRestServiceConfiguration|CentralSystemFrontEndConfiguration|WSDLEndpointConfiguration|JsonEndpointConfiguration|OCPIEndpointConfiguration|OCPIServiceConfiguration|ODataServiceConfiguration|FirebaseConfiguration|EmailConfiguration|StorageConfiguration|NotificationConfiguration|AuthorizationConfiguration|ChargingStationConfiguration|SchedulerConfiguration|LocalesConfiguration|LoggingConfiguration|HealthCheckConfiguration|MigrationConfiguration|EVDatabaseConfiguration|ChargingStationTemplatesConfiguration|AxiosConfiguration;

MODIFY
src/types/configuration/LoggingConfiguration.ts
src/types/configuration/LoggingConfiguration.ts
export default interface LoggingConfiguration {
logLevel: string;
- trace: boolean;
- traceLogOnlyStatistics: boolean;
- traceStatisticInterval: number;
- moduleDetails: {
- ChargingStation: {
- logLevel: string;
- };
- Authorizations: {
- logLevel: string;
- };
- };
}

ADD
src/types/configuration/TraceConfiguration.ts
+export default interface TraceConfiguration {
+ traceIngressHttp: boolean;
+ traceEgressHttp: boolean;
+ traceOcpp: boolean;
+ traceDatabase: boolean;
+ traceNotification: false
+}

MODIFY
src/utils/Configuration.ts
src/utils/Configuration.ts
@@ -24,6 +24,7 @@ import OICPEndpointConfiguration from '../types/configuration/OICPEndpointConfig
import OICPServiceConfiguration from '../types/configuration/OICPServiceConfiguration';
import SchedulerConfiguration from '../types/configuration/SchedulerConfiguration';
import StorageConfiguration from '../types/configuration/StorageConfiguration';
+import TraceConfiguration from '../types/configuration/TraceConfiguration';
import WSDLEndpointConfiguration from '../types/configuration/WSDLEndpointConfiguration';
import chalk from 'chalk';
import fs from 'fs';
@@ -233,6 +234,35 @@ export default class Configuration {
}
}
+ public static getTraceConfig(): TraceConfiguration {
+ let trace = Configuration.getConfig().Trace;
+ if (Configuration.isUndefined('Trace', trace)) {
+ trace = {
+ traceIngressHttp: false,
+ traceEgressHttp: false,
+ traceOcpp: false,
+ traceDatabase: false,
+ traceNotification: false,
+ };
+ }
+ if (Configuration.isUndefined('Trace.traceIngressHttp', trace.traceIngressHttp)) {
+ trace.traceIngressHttp = false;
+ }
+ if (Configuration.isUndefined('Trace.traceEgressHttp', trace.traceEgressHttp)) {
+ trace.traceEgressHttp = false;
+ }
+ if (Configuration.isUndefined('Trace.traceOcpp', trace.traceOcpp)) {
+ trace.traceOcpp = false;
+ }
+ if (Configuration.isUndefined('Trace.traceDatabase', trace.traceDatabase)) {
+ trace.traceDatabase = false;
+ }
+ if (Configuration.isUndefined('Trace.traceNotification', trace.traceNotification)) {
+ trace.traceNotification = false;
+ }
+ return trace;
+ }
+
private static getConfig(): ConfigurationData {
if (!Configuration.config) {
let configuration: ConfigurationData;

MODIFY
src/utils/Logging.ts
src/utils/Logging.ts
@@ -18,6 +18,7 @@ import { OICPResult } from '../types/oicp/OICPResult';
import PerformanceStorage from '../storage/mongodb/PerformanceStorage';
import { ServerAction } from '../types/Server';
import Tenant from '../types/Tenant';
+import TraceConfiguration from '../types/configuration/TraceConfiguration';
import User from '../types/User';
import UserToken from '../types/UserToken';
import Utils from './Utils';
@@ -28,6 +29,7 @@ const MODULE_NAME = 'Logging';
export default class Logging {
private static loggingConfig: LoggingConfiguration;
+ private static traceConfig: TraceConfiguration;
public static getConfiguration(): LoggingConfiguration {
if (!this.loggingConfig) {
@@ -36,11 +38,21 @@ export default class Logging {
return this.loggingConfig;
}
+ public static getTraceConfiguration(): TraceConfiguration {
+ if (!this.traceConfig) {
+ this.traceConfig = Configuration.getTraceConfig();
+ }
+ return this.traceConfig;
+ }
+
public static traceDatabaseRequestStart(): number {
+ if (Logging.getTraceConfiguration().traceDatabase) {
return Date.now();
}
+ }
public static async traceDatabaseRequestEnd(tenant: Tenant, module: string, method: string, timeStartMillis: number, request: any, response: any = {}): Promise<void> {
+ if (Logging.getTraceConfiguration().traceDatabase) {
// Compute duration if provided
const executionDurationMillis = new Date().getTime() - timeStartMillis;
const sizeOfRequestDataKB = Utils.truncTo(Utils.createDecimal(
@@ -95,13 +107,17 @@ export default class Logging {
})
);
}
+ }
public static traceNotificationStart(): number {
+ if (Logging.getTraceConfiguration().traceNotification) {
return Date.now();
}
+ }
public static async traceNotificationEnd(tenant: Tenant, module: string, method: string, timeStartMillis: number,
templateName: string, data: any, userID: string): Promise<void> {
+ if (Logging.getTraceConfiguration().traceNotification) {
// Compute duration if provided
const executionDurationMillis = new Date().getTime() - timeStartMillis;
const sizeOfRequestDataKB = Utils.truncTo(Utils.createDecimal(
@@ -137,6 +153,7 @@ export default class Logging {
})
);
}
+ }
public static async logDebug(log: Log): Promise<string> {
log.level = LogLevel.DEBUG;
@@ -278,6 +295,7 @@ export default class Logging {
}
public static async traceExpressRequest(req: Request, res: Response, next: NextFunction): Promise<void> {
+ if (Logging.getTraceConfiguration().traceIngressHttp) {
try {
// Get Tenant info
let userID: string;
@@ -342,9 +360,13 @@ export default class Logging {
} finally {
next();
}
+ } else {
+ next();
+ }
}
public static traceExpressResponse(req: Request, res: Response, next: NextFunction): void {
+ if (Logging.getTraceConfiguration().traceIngressHttp) {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
res.on('finish', async () => {
// Get Tenant info
@@ -418,15 +440,20 @@ export default class Logging {
await PerformanceStorage.updatePerformanceRecord(performanceRecord);
}
});
+ }
next();
}
public static async traceExpressError(error: Error, req: Request, res: Response, next: NextFunction): Promise<void> {
await Logging.logActionExceptionMessageAndSendResponse(
error['params'] && error['params']['action'] ? error['params']['action'] : ServerAction.HTTP_ERROR, error, req, res, next);
+ if (Logging.getTraceConfiguration().traceIngressHttp) {
+ // Nothing done yet
+ }
}
public static async traceAxiosRequest(tenant: Tenant, request: AxiosRequestConfig): Promise<void> {
+ if (Logging.getTraceConfiguration().traceEgressHttp) {
request['timestamp'] = new Date();
// Compute Length
const sizeOfRequestDataKB = Utils.truncTo(Utils.createDecimal(
@@ -454,8 +481,10 @@ export default class Logging {
);
request['performanceID'] = performanceID;
}
+ }
public static async traceAxiosResponse(tenant: Tenant, response: AxiosResponse): Promise<void> {
+ if (Logging.getTraceConfiguration().traceEgressHttp) {
// Compute duration
let executionDurationMillis: number;
if (response.config['timestamp']) {
@@ -542,6 +571,7 @@ export default class Logging {
});
}
}
+ }
public static async traceAxiosError(tenant: Tenant, error: AxiosError): Promise<void> {
// Error handling is done outside to get the proper module information
@@ -559,6 +589,7 @@ export default class Logging {
axiosError: Utils.objectHasProperty(error, 'toJSON') ? error.toJSON() : null,
}
});
+ if (Logging.getTraceConfiguration().traceEgressHttp) {
if (error.response?.config['performanceID']) {
let executionDurationMillis: number;
let sizeOfResponseDataKB = 0;
@@ -578,6 +609,7 @@ export default class Logging {
await PerformanceStorage.updatePerformanceRecord(performanceRecord);
}
}
+ }
public static async logException(exception: Error, action: ServerAction,
module: string, method: string, tenantID: string, user?: UserToken | User | string): Promise<void> {
@@ -645,6 +677,7 @@ export default class Logging {
public static async traceOcppMessageRequest(module: string, tenant: Tenant, chargingStationID: string,
action: ServerAction, request: any, direction: '<<' | '>>',
chargingStationDetails: { siteID: string; siteAreaID: string; companyID: string; }): Promise<PerformanceTracingData> {
+ if (Logging.getTraceConfiguration().traceOcpp) {
// Compute size
const sizeOfRequestDataKB = Utils.truncTo(Utils.createDecimal(
sizeof(request)).div(1024).toNumber(), 2);
@@ -673,10 +706,12 @@ export default class Logging {
performanceID
};
}
+ }
public static async traceOcppMessageResponse(module: string, tenant: Tenant, chargingStationID: string,
action: ServerAction, request: any, response: any, direction: '<<' | '>>',
chargingStationDetails: { siteID: string, siteAreaID: string, companyID: string,}, performanceTracingData?: PerformanceTracingData): Promise<void> {
+ if (Logging.getTraceConfiguration().traceOcpp) {
// Compute duration if provided
const executionDurationMillis = performanceTracingData?.startTimestamp ? Date.now() - performanceTracingData.startTimestamp : 0;
const sizeOfResponseDataKB = Utils.truncTo(Utils.createDecimal(
@@ -730,6 +765,7 @@ export default class Logging {
await PerformanceStorage.updatePerformanceRecord(performanceRecord);
}
}
+ }
private static async logActionException(tenantID: string, action: ServerAction, exception: any, detailedMessages = {}): Promise<void> {
await Logging.logError({
@@ -834,25 +870,10 @@ export default class Logging {
}
private static async log(log: Log): Promise<string> {
- let moduleConfig = null;
// Check Log Level
const loggingConfig = Logging.getConfiguration();
// Default Log Level
- let logLevel = loggingConfig.logLevel ? loggingConfig.logLevel : LogLevel.DEBUG;
- // Module Provided?
- if (log.module && loggingConfig.moduleDetails) {
- // Yes: Check the Module
- if (loggingConfig.moduleDetails[log.module]) {
- // Get Modules Config
- moduleConfig = loggingConfig.moduleDetails[log.module];
- // Check Module Log Level
- if (moduleConfig.logLevel) {
- if (moduleConfig.logLevel !== LogLevel.DEFAULT) {
- logLevel = moduleConfig.logLevel;
- }
- }
- }
- }
+ const logLevel = loggingConfig.logLevel ? loggingConfig.logLevel : LogLevel.DEBUG;
// Log Level
switch (LogLevel[logLevel]) {
// No logging at all

Added trace in conf