Signale

Hochgradig konfigurierbares Loggingprogramm

Header

Build Status NPM Downloads

Beschreibung

Signale ist bis ins letzte hack- und konfigurierbar. Es kann für Logging und Statusreports als auch für das Handling des Output Rendering Process von anderen Node Modulen und Anwendungen verwendet werden.

Diese Dokument in Albanian - Shqip, English, 简体中文 - Simplified Chinese lesen.

Lies die contributing guidelines um zu lernen, wie du dieses Dokument in mehr Sprachen übersetzen kannst.

Höhepunkte

Inhalt

Installation

Yarn

yarn add signale

NPM

npm install signale

Verwendung

Default Loggers

Signale importieren und einen der default Logger verwenden.

All verfügbaren Logger anzeigen.
- `await` - `complete` - `error` - `debug` - `fatal` - `fav` - `info` - `note` - `pause` - `pending` - `star` - `start` - `success` - `wait` - `warn` - `watch` - `log`


const signale = require('signale');

signale.success('Operation successful');
signale.debug('Hello', 'from', 'L59');
signale.pending('Write release notes for %s', '1.2.0');
signale.fatal(new Error('Unable to acquire lock'));
signale.watch('Recursively watching build directory...');
signale.complete({prefix: '[task]', message: 'Fix issue #59', suffix: '(@klaudiosinani)'});
Default Loggers

Benutzerdefinierte Logger

Um einen benutzerdefinierten Logger zu erzeugen, wird ein options Objekt mit einem types field mit dem Logger definiert. Als argument wird eine neue Signale Instanz übergeben.

const {Signale} = require('signale');

const options = {
  disabled: false,
  interactive: false,
  logLevel: 'info',
  scope: 'custom',
  secrets: [],
  stream: process.stdout,
  types: {
    remind: {
      badge: '**',
      color: 'yellow',
      label: 'reminder',
      logLevel: 'info'
    },
    santa: {
      badge: '🎅',
      color: 'red',
      label: 'santa',
      logLevel: 'info'
    }
  }
};

const custom = new Signale(options);
custom.remind('Improve documentation.');
custom.santa('Hoho! You have an unused variable on L45.');
Custom Loggers

Ein Beispiel, wo die voreingestellten error und success Logger überschrieben werden.

const {Signale} = require('signale');

const options = {
  types: {
    error: {
      badge: '!!',
      label: 'fatal error'
    },
    success: {
      badge: '++',
      label: 'huge success'
    }
  }
};

const signale = new Signale();
signale.error('Default Error Log');
signale.success('Default Success Log');

const custom = new Signale(options);
custom.error('Custom Error Log');
custom.success('Custom Success Log');
Default Loggers

Das options Objekt kann jedes der folgenden Attribute erhalten: disabled, interactive, logLevel, secrets, stream, scope und types.

disabled

Verhindert das Logging aller Logger, die zur der Instanz gehören.

interactive

Schaltet alle Logger, die zu der Instanz gehören, in den interaktiven Modus.

logLevel

Setzte den Loglevel der erstellten Instanz. Es kann einer der folgenden Level gewählt werden:

secrets

Ein Array, in dem geheime/sensitive Informationen angegeben werden können. Diese werden vom Body und den Metadaten der Benachtichtigungen entfernt und mit dem voreingestellten '[secure]' String ersetzt.

stream

Die Daten werden in dieses Ziel geschrieben. Es kann ein einzelner, gültiger Writable stream oder ein Array mit mehreren Writable streams sein.

scope

Name des Bereichs für den geloggt wird.

types

Enthält die Konfiguration der benutzerdefinierten und voreingestellten Logger.

Zusätzlich kann das configuration object von jedem Logger-Type, das in der types Option definiert wird, folgende Attibute erhalten: badge, label, color, logLevel & stream.

badge

Icon, der zum Logger gehört.

label

Label, das verwendet wird, um den Typ des Loggers zu erkennen.

color

Farbe des Labels. Kann eine der von chalk unterstützten Farben sein.

logLevel

Das passende Loglevel für den Logger. Nachrichten vom Logger werden angezeigt, wenn der Loglevel größer oder gleich zum oben beschriebenen generellen Loglevel logLevel der Signale Instanz ist.

Zielgerichtete Logger

Um einen neuen Logger für einen bestimmten Bereich zu erstellen, wird das scope Feld im options Objekt definiert und als Argument an die neue Signale Instanz übergeben.

const {Signale} = require('signale');

const options = {
  scope: 'global scope'
};

const global = new Signale(options);
global.success('Successful Operation');
Scope Vanilla

Um einen Logger für einen besteimmten Bereich, basierend auf einem bereits existierenden Logger, zu erstellen wird die scope() Funktion verwendet. Sie retourniert eine neue signale Instanz, die alle benutzerdefinierten Logger, Timer, Geheimnisse, Streams, Konfiguation, Loglevel, Interaktiven Modi und deaktivierten Stati erbt.

const signale = require('signale');

const global = signale.scope('global scope');
global.success('Hello from the global scope');

function foo() {
  const outer = global.scope('outer', 'scope');
  outer.success('Hello from the outer scope');
  
  setTimeout(() => {
    const inner = outer.scope('inner', 'scope'); 
    inner.success('Hello from the inner scope');
  }, 500);
}

foo();
Scope Existing

Interaktive Loggers

Um einen intaktiven Logger zu initialisieren, wird eine neue signale Instanz mit dem Wert true im interactive Attribute erzeugt. Während man sich im interaktiven Modus befindet, werden zuvor geloggte Nachrichten von einem anderen interaktiven Logger von den neuen, die von dem gleichen oder einem neuen interaktiven Logger kommen, überschrieben. Reguläre Nachrichten von regulären Loggern werden von interaktiven nicht überschrieben.

const {Signale} = require('signale');

const interactive = new Signale({interactive: true, scope: 'interactive'});

interactive.await('[%d/4] - Process A', 1);

setTimeout(() => {
  interactive.success('[%d/4] - Process A', 2);
  setTimeout(() => {
    interactive.await('[%d/4] - Process B', 3);
    setTimeout(() => {
      interactive.error('[%d/4] - Process B', 4);
      setTimeout(() => {}, 1000);
    }, 1000);
  }, 1000);
}, 1000);
Interactive Mode

Writable Streams

Standardmäßig loggen alle Signale Instanzen die Nachrichten in den process.stdout stream. Der Ziel-Stream kann durch die stream property angepasst werden. Hier kann ein einzelner oder mehrere gütlige Writable streams angegeben werden, welche dann von allen Loggertypen verwendet werden. Zusätzlich ist es möglich einen oder mehrere Wirtable Streams exklusiv für einen spezifischen Loggertypen zu definieren - also Daten unabhängig von den restlichen Loggertypen zu schreiben.

const {Signale} = require('signale');

const options = {
  stream: process.stderr, // All loggers will now write to `process.stderr`
  types: {
    error: {
      // Only `error` will write to both `process.stdout` & `process.stderr`
      stream: [process.stdout, process.stderr]
    }
  }
};

const signale = new Signale(options);
signale.success('Message will appear on `process.stderr`');
signale.error('Message will appear on both `process.stdout` & `process.stderr`');
Writable Streams

Secrets Filtering

Durch das Verwenden der secrets Option werden geheime/sensitive Informationen, wie Scopenamen, aus den Nachrichten (Body und Metadaten) herausgefiltert. Diese Option ist Teil des configuration-Objects, dass einer Signale-Instanz oder Initialisierung übergeben wird und hat den Typ Array<String|Number>. Das Array kann mehrere Geheimnisse enthalten. Alle werden, wenn sie vorkommen, entfernt und durch den standardmäßigen '[secure]' string ersetzt. Wenn die unäre signale.scope(name) Funktion verwendet wird, dann erbt die erzeugte Signale Instanz alle Geheimnisse des Parents. Die Geheimnisse werden case-sensitive überprüft. Die unäre signale.addSecrets() und die nullstellige signale.clearSecrets() Funktion sind über die API verfügbar um die Geheimnisse hinzuzufügen/zu löschen.

Es ist entscheidende und stark befürwortete Praxis, sensitive Informationen nicht direkt im Quellcode zu speichern. Das Beispiel ist alleinig zur die Demonstration gedacht:

const {Signale} = require('signale');

// In reality secrets could be securely fetched/decrypted through a dedicated API 
const [USERNAME, TOKEN] = ['klaudiosinani', 'token'];

const logger1 = new Signale({
  secrets: [USERNAME, TOKEN]
});

logger1.log('$ exporting USERNAME=%s', USERNAME);
logger1.log('$ exporting TOKEN=%s', TOKEN);

// `logger2` inherits all secrets from its parent `logger1`
const logger2 = logger1.scope('parent');

logger2.log('$ exporting USERNAME=%s', USERNAME);
logger2.log('$ exporting TOKEN=%s', TOKEN);
Secrets Filtering

Timers

Timer werden von den time() und timeEnd() Funktionen verwaltet. Zur Identifikation eines Timers oder einer Initialisierung kann ein einzigartiges Label vewrendet werden. Wenn keines bereitgestellt wird, dann wird eines automatisch generiert. Wenn die timeEnd() Funktion ohne ein Label aufgerufen wird, dann wird der als letztes initialisierte Timer terminiert, der ohne Label erstellt wurde.

const signale = require('signale');

signale.time('test');
signale.time();
signale.time();

setTimeout(() => {
  signale.timeEnd();
  signale.timeEnd();
  signale.timeEnd('test');
}, 500);
Timers

Konfiguration

Global

Um die gloabel Konfiguration zu ermöglichen, müssen die Optionen unter demsignale namespace im package.json defniert werden.

Das folgende Beispiel zeigt alle verfügbaren Optionen mit den zugehörigen voreingestellten Werten.

{
  "signale": {
    "displayScope": true,
    "displayBadge": true,
    "displayDate": false,
    "displayFilename": false,
    "displayLabel": true,
    "displayTimestamp": false,
    "underlineLabel": true,
    "underlineMessage": false,
    "underlinePrefix": false,
    "underlineSuffix": false,
    "uppercaseLabel": false
  }
}
Alle verfügbaren Optionen im Detail ansehen. ##### `displayScope` - Type: `Boolean` - Default: `true` Zeigt den Bereichsnamen des Loggers. ##### `displayBadge` - Type: `Boolean` - Default: `true` Zeigt den Badge des Loggers. ##### `displayDate` - Type: `Boolean` - Default: `false` Zeugt das aktuelle lokale Datum im `YYYY-MM-DD` Format. ##### `displayFilename` - Type: `Boolean` - Default: `false` Zeigt den Dateinamen vom File, für das der Logger loggt. ##### `displayLabel` - Type: `Boolean` - Default: `true` Zeigt das Label des Loggers. ##### `displayTimestamp` - Type: `Boolean` - Default: `false` Zeigt die lokale Zeit im `HH:MM:SS` Format. ##### `underlineLabel` - Type: `Boolean` - Default: `true` Unterstreicht das Logger-Label. ##### `underlineMessage` - Type: `Boolean` - Default: `false` Unterstreicht die Logger Nachricht. ##### `underlinePrefix` - Type: `Boolean` - Default: `false` Unterstreicht die Logger Prefix. ##### `underlineSuffix` - Type: `Boolean` - Default: `false` Unterstreicht die Logger Suffix. ##### `uppercaseLabel` - Type: `Boolean` - Default: `false` Zeigt das Label des Loggers in Großbuchstaben.

Local

Um die lokale Konfiguration zu ermöglichen muss die config() Funktion der Signale Instanz aufgerufen werden. Lokale Konfigurationen überschreiben immer die geerbte Konfiguration von package.json.

Das folgende Beispiel zeigt wie Logger in der foo.js-Datei unter einer eigenen Konfiguation laufen, die die package.json-Konfiguration überschreibt.

// foo.js
const signale = require('signale');

// Overrides any existing `package.json` config
signale.config({
  displayFilename: true,
  displayTimestamp: true,
  displayDate: false
}); 

signale.success('Hello from the Global scope');
Local Config

Logger für bestimmte Bereiche können eine unabhängige, eigene Konfiguration erhalten, die die vom Parent oder vom package.json vererbte Konfiguation überschreibt.

// foo.js
const signale = require('signale');

signale.config({
  displayFilename: true,
  displayTimestamp: true,
  displayDate: false
});

signale.success('Hello from the Global scope');

function foo() {
  // `fooLogger` inherits the config of `signale`
  const fooLogger = signale.scope('foo scope');

  // Overrides both `signale` and `package.json` configs
  fooLogger.config({
    displayFilename: true,
    displayTimestamp: false,
    displayDate: true
  });

  fooLogger.success('Hello from the Local scope');
}

foo();
Scope Config

API

signale.<logger>(message[, message]|messageObj|errorObj)

logger

Kann jeder vereingestellte oder benutzerdefinierte Logger sein.

message

Kann ein oder mehrere durch Kommas getrennte Strings sein.

const signale = require('signale');

signale.success('Successful operation');
//=> ✔  success  Successful operation

signale.success('Successful', 'operation');
//=> ✔  success  Successful operation

signale.success('Successful %s', 'operation');
//=> ✔  success  Successful operation
errorObj

Kann jedes Error Objekt sein.

const signale = require('signale');

signale.error(new Error('Unsuccessful operation'));
//=> ✖  error  Error: Unsuccessful operation
//        at Module._compile (module.js:660:30)
//        at Object.Module._extensions..js (module.js:671:10)
//        ...
messageObj

Kann jedes Objet sein, dass die Attribute prefix, message und suffix enthält, wobei prefix und suffix immer vor bzw. nach der message eingefügt werden.

const signale = require('signale');

signale.complete({prefix: '[task]', message: 'Fix issue #59', suffix: '(@klaudiosinani)'});
//=> [task] ☒  complete  Fix issue #59 (@klaudiosinani)

signale.complete({prefix: '[task]', message: ['Fix issue #%d', 59], suffix: '(@klaudiosinani)'});
//=> [task] ☒  complete  Fix issue #59 (@klaudiosinani)

signale.scope(name[, name])

Definiert den Namen des Loggers.

name

Kann ein oder mehrere durch Kommas getrennte Strings sein.

const signale = require('signale');

const foo = signale.scope('foo'); 
const fooBar = signale.scope('foo', 'bar');

foo.success('foo');
//=> [foo] › ✔  success  foo

fooBar.success('foo bar');
//=> [foo] [bar] › ✔  success  foo bar

signale.unscope()

Löscht den Bereichsnamen des Loggers.

const signale = require('signale');

const foo = signale.scope('foo'); 

foo.success('foo');
//=> [foo] › ✔  success  foo

foo.unscope();

foo.success('foo');
//=> ✔  success  foo

signale.config(settingsObj)

Die Konfiguration der Instanz wird gesestzt und überschreibt die existierende lokale oder globale Konfiguration.

settingsObj

Kann jede der dokumentierten options enthalten.

// foo.js
const signale = require('signale');

signale.config({
  displayFilename: true,
  displayTimestamp: true,
  displayDate: true
});

signale.success('Successful operations');
//=> [2018-5-15] [11:12:38] [foo.js] › ✔  success  Successful operations

signale.time([, label])

Setzt einen Timer und aktzeptiert ein optionales Label. Wenn kein Label übergeben wird, dann erhält der Timer automatisch eines.

Retourniert einen String, der das Timerlabel repräsentiert.

label

Label, dass zum Timer gehört. Jeder Timer braucht ein einzigartiges Label.

const signale = require('signale');

signale.time();
//=> ▶  timer_0  Initialized timer...

signale.time();
//=> ▶  timer_1  Initialized timer...

signale.time('label');
//=> ▶  label    Initialized timer...

signale.timeEnd([, label])

Deaktiviert den Timer, der zu dem Label gehört. Wenn kein Label angegeben wird, dann wird der letzte Timer, der ohne Label erzeugt wurde, deaktiviert.

Retourniert ein Objekt {label, span}, welches das Label und die Laufzeit enthält.

label

Label, dass zu dem Timer gehört. Jeder Timer hat ein einzigartiges label.

const signale = require('signale');

signale.time();
//=> ▶  timer_0  Initialized timer...

signale.time();
//=> ▶  timer_1  Initialized timer...

signale.time('label');
//=> ▶  label    Initialized timer...

signale.timeEnd();
//=> ◼  timer_1  Timer run for: 2ms

signale.timeEnd();
//=> ◼  timer_0  Timer run for: 2ms

signale.timeEnd('label');
//=> ◼  label    Timer run for: 2ms

signale.disable()

Deaktiviert das Logging für alle Logger die zu einer spezifischen Instanz gehören.

const signale = require('signale');

signale.success('foo');
//=> ✔  success  foo

signale.disable();

signale.success('foo');
//=>

signale.enable()

Aktiviert das Logging für alle Logger die zu einer spezifischen Instanz gehören.

const signale = require('signale');

signale.disable();

signale.success('foo');
//=>

signale.enable();

signale.success('foo');
//=> ✔  success  foo

signale.isEnabled()

Überprüft, ob Logging für die spezifische Instanz aktiviert ist.

const signale = require('signale');

signale.success('foo');
//=> ✔  success  foo

signale.isEnabled();
// => true

signale.disable();

signale.success('foo');
//=>

signale.isEnabled();
// => false

signale.addSecrets(secrets)

Fügt neue geheime/sensitive Informatioen hinzu.

secrets

Array, dass die geheime/sensitive Information enthält, die herausgefiltert werden soll.

const signale = require('signale');

signale.log('$ exporting USERNAME=%s', 'klaudiosinani');
//=> $ exporting USERNAME=klaudiosinani

signale.addSecrets(['klaudiosinani']);

signale.log('$ exporting USERNAME=%s', 'klaudiosinani');
//=> $ exporting USERNAME=[secure]

signale.clearSecrets()

Entfernt alle geheimen/sensitiven Informationen der spezifischen Signale Instanz.

const signale = require('signale');

signale.addSecrets(['klaudiosinani']);

signale.log('$ exporting USERNAME=%s', 'klaudiosinani');
//=> $ exporting USERNAME=[secure]

signale.clearSecrets();

signale.log('$ exporting USERNAME=%s', 'klaudiosinani');
//=> $ exporting USERNAME=klaudiosinani

Development

Mehr Informationen im Bezug auf Beiträge zum Projekt finden sich in den contributing guidelines.

Who’s Using It?

Repositories, die Signale verwenden im Detail ansehen: hier.

Team

License

MIT