Skip to content

Commit

Permalink
feat: Add buffering feature
Browse files Browse the repository at this point in the history
  • Loading branch information
megahertz committed Dec 5, 2024
1 parent b2269eb commit cebb269
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 3 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 5.2.4

- Add Buffering feature.

## 5.2.0

- [fix](https://github.com/megahertz/electron-log/commit/a52f3e5863ba5caf6cb19b2cdb32c43d28545b9d):
Expand Down Expand Up @@ -131,7 +135,7 @@ was implemented.
## 2.0.0
- Move log.appName property to log.transports.file.appName.
- Change a log message object.
See updated [Override transport section](README.md#override-transport) if you
See updated [Override transport section](docs/extend.md) if you
use custom transport.
- Now it's not possible to configure transports from a renderer
process, only from the main.
Expand Down
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,30 @@ userLog.info('message with user scope');
By default, scope labels are padded in logs. To disable it, set
`log.scope.labelPadding = false`.

### Buffering

It's like a transaction, you may add some logs to the buffer and then decide
whether to write these logs or not. It allows adding verbose logs only
when some operations failed.

```js
import log from 'electron-log/main';

log.buffering.begin();
try {
log.info('First silly message');
// do somethings complex
log.info('Second silly message');
// do something else

// Finished fine, we don't need these logs anymore
log.buffering.reject();
} catch (e) {
log.buffering.commit();
log.warn(e);
}
```

## Related

- [electron-cfg](https://github.com/megahertz/electron-cfg) -
Expand Down
34 changes: 34 additions & 0 deletions src/core/Buffering.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict';

class Buffering {
constructor({ processMessage }) {
this.processMessage = processMessage;
this.buffer = [];
this.enabled = false;

this.begin = this.begin.bind(this);
this.commit = this.commit.bind(this);
this.reject = this.reject.bind(this);
}

addMessage(message) {
this.buffer.push(message);
}

begin() {
this.enabled = [];
}

commit() {
this.enabled = false;
this.buffer.forEach((item) => this.processMessage(item));
this.buffer = [];
}

reject() {
this.enabled = false;
this.buffer = [];
}
}

module.exports = Buffering;
10 changes: 8 additions & 2 deletions src/core/Logger.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const scopeFactory = require('./scope');
const Buffering = require('./Buffering');

/**
* @property {Function} error
Expand Down Expand Up @@ -44,14 +45,15 @@ class Logger {
this.processMessage = this.processMessage.bind(this);

this.allowUnknownLevel = allowUnknownLevel;
this.buffering = new Buffering(this);
this.dependencies = dependencies;
this.initializeFn = initializeFn;
this.isDev = isDev;
this.levels = levels;
this.logId = logId;
this.scope = scopeFactory(this);
this.transportFactories = transportFactories;
this.variables = variables || {};
this.scope = scopeFactory(this);

for (const name of this.levels) {
this.addLevel(name, false);
Expand Down Expand Up @@ -128,7 +130,11 @@ class Logger {
}

logData(data, options = {}) {
this.processMessage({ data, ...options });
if (this.buffering.enabled) {
this.buffering.addMessage({ data, ...options });
} else {
this.processMessage({ data, ...options });
}
}

processMessage(message, { transports = this.transports } = {}) {
Expand Down
49 changes: 49 additions & 0 deletions src/core/__specs__/Buffering.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict';

const { expect } = require('humile');
const Logger = require('../Logger');

describe('Buffering', () => {
it('should write messages when commit is called', () => {
const { log, written } = createLogger();

log.info('before');

log.buffering.begin();
log.info('buffered');
expect(written).toEqual(['before']);

log.buffering.commit();
log.info('after');
expect(written).toEqual(['before', 'buffered', 'after']);
});

it('should discard messages when reject is called', () => {
const { log, written } = createLogger();

log.info('before');

log.buffering.begin();
log.info('buffered');
expect(written).toEqual(['before']);

log.buffering.reject();
log.info('after');
expect(written).toEqual(['before', 'after']);
});
});

function createLogger() {
const written = [];

function variableWriteFactory() {
return (msg) => {
written.push(msg.data.join(' '));
};
}

return {
log: new Logger({ transportFactories: [variableWriteFactory] }),
written,
};
}
29 changes: 29 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,30 @@ declare namespace Logger {
[key: string]: Transport | null;
}

interface Buffering {
/**
* Buffered log messages
*/
buffer: LogMessage[];

enabled: boolean;

/**
* Start buffering log messages
*/
begin(): void;

/**
* Stop buffering and process all buffered logs
*/
commit(): void;

/**
* Stop buffering and discard all buffered logs
*/
reject(): void;
}

interface Scope {
(label: string): LogFunctions;

Expand Down Expand Up @@ -553,6 +577,11 @@ declare namespace Logger {
}

interface Logger extends LogFunctions {
/**
* Buffering helper
*/
buffering: Buffering;

/**
* Error handling helper
*/
Expand Down

0 comments on commit cebb269

Please sign in to comment.