Skip to content

Instantly share code, notes, and snippets.

@zplume
Last active December 12, 2017 13:55
Show Gist options
  • Save zplume/3ee17bf85ca6a29c7e80d3209a61531a to your computer and use it in GitHub Desktop.
Save zplume/3ee17bf85ca6a29c7e80d3209a61531a to your computer and use it in GitHub Desktop.

Log.ts

Simple class for writing to the console with TypeScript / SPFx projects

Features

  • Log levels: log, info, warn, error
  • Support for multiple arguments
  • Stringify non-string argument types
  • Displays application name, class name, function name and specified arguments

Usage

import Log from "./Log"

// the name of your application, used across modules/classes
const applicationName: string = "SomeApplication";

export default class SomeClass {
	// create an instance of the Log class, with a reference to the current class
	private log: Log = new Log(applicationName, this, "SomeClass");
								
	constructor() {
		// pass the calling method (in this case the constructor) as the first argument
	   	// and the data you want to log as the subsequent arguments
		this.log.info(this.constructor, "Testing log");
		// [SomeApplication][SomeClass][constructor]: Testing log		
	   	
		this.log.info(this.constructor, { guacamole: ["avocado", "chilli", "lime", "salt", "pepper"] });
		// [SomeApplication][SomeClass][constructor]: {"guacamole":["avocado","chilli","lime","salt","pepper"]}
				   
	   	this.log.info(this.constructor, 42, "orange");
		// [SomeApplication][SomeClass][constructor]: 42, orange
				   
	   	// sometimes just logging method invocation is useful
		this.log.info(this.constructor);
		// [SomeApplication][SomeClass][constructor]
				   
		// also supported, with the same syntax:
		// - this.log.log
		// - this.log.warn
		// - this.log.error
	}
}
export default class Log {
private prefix: string;
private logSource: object;
private parseArgument(arg: any): string {
return typeof(arg) === "string" ? arg : JSON.stringify(arg);
}
private getMethodName(callingFunction: Function): string {
const methodNames = Object.getOwnPropertyNames(Object.getPrototypeOf(this.logSource));
return methodNames.filter(key => {
return this.logSource[key] === callingFunction;
})[0];
}
private logToConsole(callingFunction: Function, logFunction: Function, ...args: any[]): void {
const logContent = args.length > 0 ? ": " + args.map(arg => this.parseArgument(arg)).join(", ") : "";
logFunction(`${this.prefix}[${this.getMethodName(callingFunction)}]${logContent}`);
}
public log(callingFunction: Function, ...args: any[]): void {
const log = console.log.bind(console);
this.logToConsole(callingFunction, log, ...args);
}
public info(callingFunction: Function, ...args: any[]): void {
const log = console.info.bind(console);
this.logToConsole(callingFunction, log, ...args);
}
public warn(callingFunction: Function, ...args: any[]): void {
const log = console.warn.bind(console);
this.logToConsole(callingFunction, log, ...args);
}
public error(callingFunction: Function, ...args: any[]): void {
const log = console.error.bind(console);
this.logToConsole(callingFunction, log, ...args);
}
constructor(applicationName: string, logSource: object, className: string) {
this.logSource = logSource;
this.prefix = `[${applicationName}][${className}]`;
// Previously this.prefix used logSource.constructor["name"]
// for displaying the class name, instead of passing
// the class name explicitly via the className variable.
// Unfortunately, logSource.constructor["name"] gets renamed
// by webpack during minification so this isn't viable.
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment