Skip to content

Commit

Permalink
Update node & C# loggers to match python.
Browse files Browse the repository at this point in the history
  • Loading branch information
shachlanAmazon committed Sep 11, 2023
1 parent 59ddd20 commit 22b2adc
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 56 deletions.
2 changes: 1 addition & 1 deletion benchmarks/csharp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ private static int number_of_iterations(int num_of_concurrent_tasks)
public static async Task Main(string[] args)
{
// Demo - Setting the internal logger to log every log that has a level of info and above, and save the logs to the first.log file.
Logger.SetConfig(Level.Info, "first.log");
Logger.SetLoggerConfig(Level.Info, "first.log");
CommandLineOptions options = new CommandLineOptions();
Parser.Default
.ParseArguments<CommandLineOptions>(args).WithParsed<CommandLineOptions>(parsed => { options = parsed; });
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/node/node_benchmark.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RedisClient, RedisClusterClient, setLoggerConfig } from "babushka-rs";
import { RedisClient, RedisClusterClient, Logger } from "babushka-rs";
import commandLineArgs from "command-line-args";
import { writeFileSync } from "fs";
import percentile from "percentile";
Expand All @@ -11,7 +11,7 @@ enum ChosenAction {
SET,
}
// Demo - Setting the internal logger to log every log that has a level of info and above, and save the logs to the first.log file.
setLoggerConfig("info", "first.log");
Logger.setLoggerConfig("info", "first.log");

const PORT = 6379;
function getAddress(host: string, port?: number): string {
Expand Down
7 changes: 3 additions & 4 deletions csharp/lib/Logger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ Only one instance of this class can exist at any given time. The logger can be s
1. By calling init, which creates and modifies a new logger only if one doesn't exist.
2. By calling setConfig, which replaces the existing logger, and means that new logs will not be saved with the logs that were sent before the call.
If no call to any of these function is received, the first log attempt will initialize a new logger with default level decided by rust core (normally - console, error).
External users shouldn't user Logger, and instead setLoggerConfig Before starting to use the client.
*/
public class Logger
{
Expand All @@ -37,7 +36,7 @@ internal static void Init(Level? level, string? filename = null)
{
if (Logger.loggerLevel is null)
{
SetConfig(level, filename);
SetLoggerConfig(level, filename);
}
}

Expand All @@ -50,7 +49,7 @@ internal static void Log(Level logLevel, string logIdentifier, string message)
{
if (Logger.loggerLevel is null)
{
SetConfig(logLevel);
SetLoggerConfig(logLevel);
}
if (!(logLevel <= Logger.loggerLevel)) return;
log(Convert.ToInt32(logLevel), Encoding.UTF8.GetBytes(logIdentifier), Encoding.UTF8.GetBytes(message));
Expand All @@ -64,7 +63,7 @@ internal static void Log(Level logLevel, string logIdentifier, string message)
// 2. external user want to set the logger and we don't want to return to him the logger itself, just config it
// the level argument is the level of the logs you want the system to provide (error logs, warn logs, etc.)
// the filename argument is optional - if provided the target of the logs will be the file mentioned, else will be the console
public static void SetConfig(Level? level, string? filename = null)
public static void SetLoggerConfig(Level? level, string? filename = null)
{
var buffer = filename is null ? null : Encoding.UTF8.GetBytes(filename);
Logger.loggerLevel = InitInternalLogger(Convert.ToInt32(level), buffer);
Expand Down
10 changes: 5 additions & 5 deletions examples/node/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RedisClient, RedisClusterClient, setLoggerConfig } from "babushka-rs";
import { Logger, RedisClient, RedisClusterClient } from "babushka-rs";

async function sendPingToNode() {
// When in Redis is in standalone mode, add address of the primary node, and any replicas you'd like to be able to read from.
Expand All @@ -17,7 +17,7 @@ async function sendPingToNode() {
const pong = await client.customCommand("PING", []);
console.log(pong);
await send_set_and_get(client);
client.dispose()
client.dispose();
}

async function send_set_and_get(client: RedisClient | RedisClusterClient) {
Expand All @@ -44,15 +44,15 @@ async function sendPingToRandomNodeInCluster() {
const pong = await client.customCommand("PING", [], "randomNode");
console.log(pong);
await send_set_and_get(client);
client.dispose()
client.dispose();
}

function setFileLogger() {
setLoggerConfig("warn", "babushka.log");
Logger.setLoggerConfig("warn", "babushka.log");
}

function setConsoleLogger() {
setLoggerConfig("warn");
Logger.setLoggerConfig("warn");
}

setFileLogger();
Expand Down
2 changes: 1 addition & 1 deletion node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export {
RedisError as RequestError,
TimeoutError,
} from "./src/Errors";
export { setLoggerConfig } from "./src/Logger";
export { Logger } from "./src/Logger";
export { RedisClient } from "./src/RedisClient";
export { RedisClusterClient } from "./src/RedisClusterClient";
export { ClusterTransaction, Transaction } from "./src/Transaction";
8 changes: 4 additions & 4 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export class BaseClient {
} else {
// Unhandled error
const err_message = `Failed to decode the response: ${err}`;
Logger.instance.log("error", "connection", err_message);
Logger.log("error", "connection", err_message);
this.dispose(err_message);
return;
}
Expand Down Expand Up @@ -170,7 +170,7 @@ export class BaseClient {

protected constructor(socket: net.Socket, options?: ConnectionOptions) {
// if logger has been initialized by the external-user on info level this log will be shown
Logger.instance.log("info", "Client lifetime", `construct client`);
Logger.log("info", "Client lifetime", `construct client`);
this.responseTimeout =
options?.responseTimeout ?? DEFAULT_TIMEOUT_IN_MILLISECONDS;
this.socket = socket;
Expand Down Expand Up @@ -381,7 +381,7 @@ export class BaseClient {
this.promiseCallbackFunctions.forEach(([, reject]) => {
reject(new ClosingError(errorMessage));
});
Logger.instance.log("info", "Client lifetime", "disposing of client");
Logger.log("info", "Client lifetime", "disposing of client");
this.socket.end();
}

Expand All @@ -397,7 +397,7 @@ export class BaseClient {
): Promise<TConnection> {
const connection = constructor(connectedSocket, options);
await connection.connectToServer(options);
Logger.instance.log("info", "Client lifetime", "connected to server");
Logger.log("info", "Client lifetime", "connected to server");
return connection;
}

Expand Down
60 changes: 25 additions & 35 deletions node/src/Logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ const LEVEL: Map<LevelOptions | undefined, Level | undefined> = new Map([
type LevelOptions = "error" | "warn" | "info" | "debug" | "trace";

/*
A class that allows logging which is consistent with logs from the internal rust core.
Only one instance of this class can exist at any given time. The logger can be set up in 2 ways -
1. By calling init, which creates and modifies a new logger only if one doesn't exist.
2. By calling setConfig, which replaces the existing logger, and means that new logs will not be saved with the logs that were sent before the call.
If no call to any of these function is received, the first log attempt will initialize a new logger with default level decided by rust core (normally - console, error).
External users shouldn't user Logger, and instead setLoggerConfig Before starting to use the client.
A singleton class that allows logging which is consistent with logs from the internal rust core.
The logger can be set up in 2 ways -
1. By calling init, which configures the logger only if it wasn't previously configured.
2. By calling Logger.setLoggerConfig, which replaces the existing configuration, and means that new logs will not be saved with the logs that were sent before the call. The previous logs will remain
If no call to any of these function is received, the first log attempt will configure the logger with default configuration decided by rust core (normally - console, error).
*/
export class Logger {
private static _instance: Logger;
Expand All @@ -26,46 +25,37 @@ export class Logger {
Logger.logger_level = InitInternalLogger(LEVEL.get(level), fileName);
}

// Initialize a logger instance if none were initialized before - this method is meant to be used when there is no intention to replace an existing logger.
// The logger will filter all logs with a level lower than the given level,
// If given a fileName argument, will write the logs to files postfixed with fileName. If fileName isn't provided, the logs will be written to the console.
public static init(level?: LevelOptions, fileName?: string) {
return this._instance || (this._instance = new this(level, fileName));
}

// returning the logger instance - if doesn't exist initiate new with default config decided by rust core
public static get instance() {
return this._instance || (this._instance = new this());
}

// config the logger instance - in fact - create new logger instance with the new args
// exist in addition to init for two main reason's:
// 1. if Babushka dev want intentionally to change the logger instance configuration
// 2. external user want to set the logger and we don't want to return to him the logger itself, just config it
// the level argument is the level of the logs you want the system to provide (error logs, warn logs, etc.)
// the filename argument is optional - if provided the target of the logs will be the file mentioned, else will be the console
public static setConfig(level: LevelOptions, fileName?: string) {
this._instance = new this(level, fileName);
return;
}

// take the arguments from the user and provide to the core-logger (see ../logger-core)
// if the level is higher then the logger level (error is 0, warn 1, etc.) simply return without operation
// if a logger instance doesn't exist, create new one with default mode (decided by rust core, normally - level: error, target: console)
// logIdentifier arg is a string contain data that suppose to give the log a context and make it easier to find certain type of logs.
// when the log is connect to certain task the identifier should be the task id, when the log is not part of specific task the identifier should give a context to the log - for example, "socket connection".
public log(logLevel: LevelOptions, logIdentifier: string, message: string) {
// External users shouldn't use this function.
public static log(
logLevel: LevelOptions,
logIdentifier: string,
message: string
) {
if (!Logger._instance) {
new Logger();
}
const level = LEVEL.get(logLevel) || 0;
if (!(level <= Logger.logger_level)) return;
log(level, logIdentifier, message);
}
}

// This function is the interface for logging that will be provided to external user
// for more details see setConfig function above
export function setLoggerConfig(level: LevelOptions, fileName?: string) {
Logger.setConfig(level, fileName);
// Initialize a logger if it wasn't initialized before - this method is meant to be used when there is no intention to replace an existing logger.
// The logger will filter all logs with a level lower than the given level,
// If given a fileName argument, will write the logs to files postfixed with fileName. If fileName isn't provided, the logs will be written to the console.
public static init(level?: LevelOptions, fileName?: string) {
return this._instance || (this._instance = new this(level, fileName));
}

// configure the logger.
// the level argument is the level of the logs you want the system to provide (error logs, warn logs, etc.)
// the filename argument is optional - if provided the target of the logs will be the file mentioned, else will be the console
public static setLoggerConfig(level: LevelOptions, fileName?: string) {
this._instance = new this(level, fileName);
return;
}
}
4 changes: 2 additions & 2 deletions node/tests/RedisClientInternals.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import { Reader } from "protobufjs";
import {
ClosingError,
ConnectionOptions,
Logger,
RedisClient,
RedisClusterClient,
RequestError,
TimeoutError,
setLoggerConfig,
} from "../build-ts";
import {
connection_request,
Expand All @@ -23,7 +23,7 @@ import {
const { RequestType, RedisRequest } = redis_request;

beforeAll(() => {
setLoggerConfig("info");
Logger.init("info");
});

enum ResponseType {
Expand Down
4 changes: 2 additions & 2 deletions node/tests/TestUtilities.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { beforeAll, expect } from "@jest/globals";
import { exec } from "child_process";
import { v4 as uuidv4 } from "uuid";
import { setLoggerConfig } from "..";
import { Logger } from "..";

beforeAll(() => {
setLoggerConfig("info");
Logger.init("info");
});

export type Client = {
Expand Down

0 comments on commit 22b2adc

Please sign in to comment.