Skip to content
This repository was archived by the owner on Apr 13, 2025. It is now read-only.

Commit 2b78f80

Browse files
Add Log Prefix for logs in an instance (#275)
* Add Log Prefix for logs in an instance with custom looger Move all nessesaries nodecg.log to logger function * Fix instanceName in stopClient in core * Merge branch 'master' into 'feature/155-service-instance-name' * Fix test failures caused by additionally passed logger Co-authored-by: Daniel Huber <[email protected]> Co-authored-by: Daniel <[email protected]>
1 parent d4b0993 commit 2b78f80

File tree

52 files changed

+259
-219
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+259
-219
lines changed

nodecg-io-core/extension/__tests__/instanceManager.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ describe("InstanceManager", () => {
148148
expect(instanceManager.deleteServiceInstance(testInstance)).toBe(true);
149149

150150
expect(testService.stopClient).toHaveBeenCalledTimes(1);
151-
expect(testService.stopClient).toHaveBeenCalledWith(testServiceInstance.client);
151+
expect(testService.stopClient.mock.calls[0][0]).toBe(testServiceInstance.client);
152152
});
153153

154154
test("should log error if client cannot be stopped because the service could not be found", () => {
@@ -344,7 +344,7 @@ describe("InstanceManager", () => {
344344
expect(inst.client).toBeDefined();
345345
expect(inst.client?.()).toBe(inst.config);
346346
expect(testService.createClient).toHaveBeenCalledTimes(1);
347-
expect(testService.createClient).toHaveBeenCalledWith(inst.config);
347+
expect(testService.createClient.mock.calls[0][0]).toBe(inst.config);
348348
});
349349

350350
test("should create client if no config is required, even if config is undefined", async () => {
@@ -477,7 +477,7 @@ describe("InstanceManager", () => {
477477

478478
expect(svc.removeHandlers).not.toHaveBeenCalled();
479479
expect(svc.createClient).toHaveBeenCalledTimes(1);
480-
expect(svc.createClient).toHaveBeenCalledWith(inst.config);
480+
expect(svc.createClient.mock.calls[0][0]).toBe(inst.config);
481481
});
482482

483483
test("should do nothing if removeHandlers is not implemented by the service", () => {

nodecg-io-core/extension/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { InstanceManager } from "./instanceManager";
66
import { Service } from "./service";
77
import { PersistenceManager } from "./persistenceManager";
88
import { ServiceProvider } from "./serviceProvider";
9-
9+
import { Logger } from "./utils/logger";
1010
/**
1111
* Main type of NodeCG extension that the core bundle exposes.
1212
* Contains references to all internal modules.
@@ -88,7 +88,7 @@ function onExit(
8888
if (!service.failed && client) {
8989
nodecg.log.info(`Stopping service ${key} of type ${service.result.serviceType}.`);
9090
try {
91-
service.result.stopClient(client);
91+
service.result.stopClient(client, new Logger(key, nodecg));
9292
} catch (err) {
9393
nodecg.log.info(
9494
`Could not stop service ${key} of type ${service.result.serviceType}: ${String(err)}`,

nodecg-io-core/extension/instanceManager.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ServiceManager } from "./serviceManager";
55
import { BundleManager } from "./bundleManager";
66
import Ajv from "ajv";
77
import { EventEmitter } from "events";
8-
8+
import { Logger } from "./utils/logger";
99
/**
1010
* Manages instances of services and their configs/clients.
1111
*/
@@ -105,7 +105,7 @@ export class InstanceManager extends EventEmitter {
105105
} else {
106106
this.nodecg.log.info(`Successfully stopped client of service instance "${instanceName}".`);
107107
try {
108-
svc.result.stopClient(instance.client);
108+
svc.result.stopClient(instance.client, new Logger(instanceName, this.nodecg));
109109
} catch (e) {
110110
this.nodecg.log.error(`Couldn't stop service instance: ${e}`);
111111
}
@@ -172,7 +172,10 @@ export class InstanceManager extends EventEmitter {
172172

173173
// Validation by the service.
174174
try {
175-
const validationRes = await service.result.validateConfig(config);
175+
const validationRes = await service.result.validateConfig(
176+
config,
177+
new Logger(instanceName, this.nodecg),
178+
);
176179
if (validationRes.failed) {
177180
throw validationRes.errorMessage;
178181
}
@@ -220,7 +223,7 @@ export class InstanceManager extends EventEmitter {
220223
// If the service does not require a config we can safely ignore the undefined error because in that case
221224
// passing undefined is the intended behavior.
222225
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
223-
const client = await service.createClient(inst.config!);
226+
const client = await service.createClient(inst.config!, new Logger(instanceName, this.nodecg));
224227

225228
// Check if a error happened while creating the client
226229
if (client.failed) {
@@ -230,7 +233,7 @@ export class InstanceManager extends EventEmitter {
230233
inst.client = client.result;
231234
}
232235
} catch (err) {
233-
const msg = `The "${inst.serviceType}" service produced an error while creating a client: ${err}`;
236+
const msg = `The "${inst.serviceType}" service with the name "${instanceName}" produced an error while creating a client: ${err}`;
234237
this.nodecg.log.error(msg);
235238
inst.client = undefined;
236239
return error(msg);
@@ -244,7 +247,7 @@ export class InstanceManager extends EventEmitter {
244247
if (oldClient !== undefined) {
245248
this.nodecg.log.info(`Stopping old unused ${inst.serviceType} client...`);
246249
try {
247-
service.stopClient(oldClient);
250+
service.stopClient(oldClient, new Logger(instanceName, this.nodecg));
248251
} catch (e) {
249252
this.nodecg.log.error(`Couldn't stop service instance: ${e}`);
250253
}

nodecg-io-core/extension/service.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { Result } from "./utils/result";
44
import { ServiceProvider } from "./serviceProvider";
5+
import { Logger } from "./utils/logger";
56

67
/**
78
* Models a map using a object, instead of a iterator like the javascript es6 map.
@@ -48,26 +49,29 @@ export interface Service<R, C> {
4849
* This function validates the passed config after it has been validated against the json schema (if applicable).
4950
* Should make deeper checks like checking validity of auth tokens.
5051
* @param config the config which should be validated.
52+
* @param logger the logger which logs with the instance.name as prefix
5153
* @return void if the config passes validation and an error string describing the issue if not.
5254
*/
53-
validateConfig(config: R): Promise<Result<void>>;
55+
validateConfig(config: R, logger: Logger): Promise<Result<void>>;
5456

5557
/**
5658
* Creates a client to the service using the validated config.
5759
* The returned result will be passed to bundles and they should be able to use the service with this returned client.
5860
*
5961
* @param config the user provided config for the service.
62+
* @param logger the logger which logs with the instance.name as prefix
6063
* @return the client if everything went well and an error string describing the issue if a error occured.
6164
*/
62-
createClient(config: R): Promise<Result<C>>;
65+
createClient(config: R, logger: Logger): Promise<Result<C>>;
6366

6467
/**
6568
* Stops a client of this service that is not needed anymore.
6669
* Services should close any connections that might exist here.
6770
*
6871
* @param client the client that needs to be stopped.
72+
* @param logger the logger which logs with the instance.name as prefix
6973
*/
70-
stopClient(client: C): void;
74+
stopClient(client: C, logger: Logger): void;
7175

7276
/**
7377
* Removes all handlers from a service client.

nodecg-io-core/extension/serviceBundle.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Result } from "./utils/result";
55

66
import * as fs from "fs";
77
import * as path from "path";
8+
import { Logger } from "./utils/logger";
89

910
/**
1011
* Class helping to create a nodecg-io service
@@ -42,7 +43,6 @@ export abstract class ServiceBundle<R, C> implements Service<R, C> {
4243
this.nodecg = nodecg;
4344
this.serviceType = serviceName;
4445
this.schema = this.readSchema(pathSegments);
45-
4646
this.nodecg.log.info(this.serviceType + " bundle started.");
4747
this.core = this.nodecg.extensions["nodecg-io-core"] as unknown as NodeCGIOCore | undefined;
4848
if (this.core === undefined) {
@@ -64,26 +64,29 @@ export abstract class ServiceBundle<R, C> implements Service<R, C> {
6464
* This function validates the passed config after it has been validated against the json schema (if applicable).
6565
* Should make deeper checks like checking validity of auth tokens.
6666
* @param config the config which should be validated.
67+
* @param logger the logger which logs with the instance.name as prefix
6768
* @return void if the config passes validation and an error string describing the issue if not.
6869
*/
69-
abstract validateConfig(config: R): Promise<Result<void>>;
70+
abstract validateConfig(config: R, logger: Logger): Promise<Result<void>>;
7071

7172
/**
7273
* Creates a client to the service using the validated config.
7374
* The returned result will be passed to bundles and they should be able to use the service with this returned client.
7475
*
7576
* @param config the user provided config for the service.
77+
* @param logger the logger which logs with the instance.name as prefix
7678
* @return the client if everything went well and an error string describing the issue if a error occured.
7779
*/
78-
abstract createClient(config: R): Promise<Result<C>>;
80+
abstract createClient(config: R, logger: Logger): Promise<Result<C>>;
7981

8082
/**
8183
* Stops a client of this service that is not needed anymore.
8284
* Services should close any connections that might exist here.
8385
*
8486
* @param client the client that needs to be stopped.
87+
* @param logger the logger which logs with the instance.name as prefix
8588
*/
86-
abstract stopClient(client: C): void;
89+
abstract stopClient(client: C, logger: Logger): void;
8790

8891
/**
8992
* Removes all handlers from a service client.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
import { NodeCG } from "nodecg-types/types/server";
3+
4+
export class Logger {
5+
constructor(private name: string, private nodecg: NodeCG) {}
6+
trace(...args: any[]): void {
7+
this.nodecg.log.trace(`[${this.name}] ${args[0]}`, ...args.slice(1));
8+
}
9+
10+
debug(...args: any[]): void {
11+
this.nodecg.log.debug(`[${this.name}] ${args[0]}`, ...args.slice(1));
12+
}
13+
14+
info(...args: any[]): void {
15+
this.nodecg.log.info(`[${this.name}] ${args[0]}`, ...args.slice(1));
16+
}
17+
18+
warn(...args: any[]): void {
19+
this.nodecg.log.warn(`[${this.name}] ${args[0]}`, ...args.slice(1));
20+
}
21+
22+
error(...args: any[]): void {
23+
this.nodecg.log.error(`[${this.name}] ${args[0]}`, ...args.slice(1));
24+
}
25+
}

nodecg-io-core/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ export type { ObjectMap, Service, ServiceDependency, ServiceInstance } from "./e
66
export * from "./extension/utils/result";
77
export * from "./extension/serviceBundle";
88
export * from "./extension/serviceProvider";
9+
export * from "./extension/utils/logger";

services/nodecg-io-ahk/extension/AHK.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import fetch from "node-fetch";
2-
import { NodeCG } from "nodecg-types/types/server";
2+
import { Logger } from "nodecg-io-core";
33

44
export class AHK {
55
private readonly address: string;
66

7-
public constructor(private nodecg: NodeCG, host: string, port: number) {
7+
public constructor(private logger: Logger, host: string, port: number) {
88
this.address = `http://${host}:${port}`;
99
}
1010

@@ -17,7 +17,7 @@ export class AHK {
1717
try {
1818
await fetch(`${this.address}/send/${command}`, { method: "GET" });
1919
} catch (err) {
20-
this.nodecg.log.error(`Error while using the AHK Connector: ${err}`);
20+
this.logger.error(`Error while using the AHK Connector: ${err}`);
2121
}
2222
}
2323
}

services/nodecg-io-ahk/extension/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { NodeCG } from "nodecg-types/types/server";
2-
import { Result, emptySuccess, success, ServiceBundle } from "nodecg-io-core";
2+
import { Result, emptySuccess, success, ServiceBundle, Logger } from "nodecg-io-core";
33
import { AHK } from "./AHK";
44

55
interface AHKServiceConfig {
@@ -14,14 +14,14 @@ module.exports = (nodecg: NodeCG) => {
1414
};
1515

1616
class AhkService extends ServiceBundle<AHKServiceConfig, AHKServiceClient> {
17-
async validateConfig(config: AHKServiceConfig): Promise<Result<void>> {
18-
const ahk = new AHK(this.nodecg, config.host, config.port);
17+
async validateConfig(config: AHKServiceConfig, logger: Logger): Promise<Result<void>> {
18+
const ahk = new AHK(logger, config.host, config.port);
1919
await ahk.testConnection(); // Will throw an error if server doesn't exist.
2020
return emptySuccess();
2121
}
2222

23-
async createClient(config: AHKServiceConfig): Promise<Result<AHKServiceClient>> {
24-
const ahk = new AHK(this.nodecg, config.host, config.port);
23+
async createClient(config: AHKServiceConfig, logger: Logger): Promise<Result<AHKServiceClient>> {
24+
const ahk = new AHK(logger, config.host, config.port);
2525
return success(ahk);
2626
}
2727

services/nodecg-io-android/extension/android.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { spawn } from "child_process";
44
import { onExit, readableToString } from "@rauschma/stringio";
55
import { AddressInfo } from "net";
66
import { buffer as readableToBuffer } from "get-stream";
7-
import { NodeCG } from "nodecg-types/types/server";
7+
import { Logger } from "nodecg-io-core";
88

99
/**
1010
* Represents an android device that is connected via ADB.
@@ -29,7 +29,7 @@ export class Android {
2929
public readonly contactManager: ContactManager;
3030
public readonly fileManager: FileManager;
3131

32-
constructor(private nodecg: NodeCG, device: string) {
32+
constructor(private logger: Logger, device: string) {
3333
this.device = device;
3434
this.connected = false;
3535

@@ -95,7 +95,7 @@ export class Android {
9595
try {
9696
await handler();
9797
} catch (err) {
98-
this.nodecg.log.error(`A disconnect handler for nodecg-io-android threw an error: ${err}`);
98+
this.logger.error(`A disconnect handler for nodecg-io-android threw an error: ${err}`);
9999
}
100100
}
101101
await this.rawRequest("cancel_all_subscriptions", {});

0 commit comments

Comments
 (0)