Permalink
Browse files

Merge pull request #1299 from input-output-hk/feature/ddw-517-impleme…

…nt-structured-logging-for-daedalus-logs

[DDW-517] Implement Structured Logging for Daedalus Logs
  • Loading branch information...
nikolaglumac committed Feb 9, 2019
2 parents f42918b + 9c163fd commit 411a09e0dd25ebd1df6c934d6a928a578f73b51b
@@ -5,6 +5,7 @@ Changelog

### Features

- Structured the Daedalus logs in the same format as the Cardano logs, which follows the structured logging specification ([PR 1299](https://github.com/input-output-hk/daedalus/pull/1299))
- Implemented an extra explanation line in the Create Paper Wallet Certificate dialog ([PR 1309](https://github.com/input-output-hk/daedalus/pull/1309))
- Improve performance of rendering huge lists of transactions and addresses ([PR 1276](https://github.com/input-output-hk/daedalus/pull/1276), [PR 1303](https://github.com/input-output-hk/daedalus/pull/1303), [PR 1305](https://github.com/input-output-hk/daedalus/pull/1305), ([PR 1306](https://github.com/input-output-hk/daedalus/pull/1306)))
- Implemented a "System-info.json" file, containing the system specification of the machine user is running Daedalus ([PR 1292](https://github.com/input-output-hk/daedalus/pull/1292))
@@ -17,6 +17,7 @@ export type Environment = {
buildNumber: string,
buildLabel: string,
platform: string,
platformVersion: string,
os: string,
installerVersion: string,
version: string,
@@ -0,0 +1,50 @@
// @flow
export type FormatMessageContextParams = {
appName: string,
electronProcess: string,
level: string,
network: string,
};

export type ConstructMessageBodyParams = {
at: string,
env: string,
ns?: Array<?string>,
data?: ?Object,
app?: Array<?string>,
msg: string,
pid: number | string,
sev: string,
thread: number | string,
};

export type MessageBody = {
at: string,
env: string,
ns: Array<?string>,
data: Object,
app: Array<?string>,
msg: string,
pid: number | string,
sev: string,
thread: number | string,
};

export type ElectronLoggerMessage = {
date: Date,
data: Array<*>,
level: string,
};

export type LogSystemInfoParams = {
cardanoVersion: string,
cpu: Array<Object>,
current: string,
daedalusVersion: string,
isInSafeMode: string,
network: string,
osName: string,
platformVersion: string,
ram: string,
startTime: string,
};
@@ -1,6 +1,87 @@
// @flow
import { pickBy } from 'lodash';
import type {
FormatMessageContextParams,
ConstructMessageBodyParams,
MessageBody,
ElectronLoggerMessage,
} from '../types/logging.types';

const DEFAULT_MESSAGE_BODY = {
ns: ['daedalus'],
data: {},
app: ['daedalus'],
};

const isProd = process.env.NODE_ENV === 'production';

const stringifyMessageBody = (messageBody: MessageBody): string => {
const spacing = isProd ? 0 : 2;
return JSON.stringify(messageBody, null, spacing);
};

export const filterLogData = (data: Object): Object => {
const sensitiveData = [
'spendingPassword', 'oldPassword', 'newPassword',
'mnemonic', 'recoveryPhrase', 'passphrase', 'password',
];
return pickBy(data, (value, key) => {
if (sensitiveData.includes(key)) { return false; }
return true;
});
};

export const stringifyData = (data: any) => JSON.stringify(data, null, 2);

export const stringifyError = (error: any) => (
JSON.stringify(error, Object.getOwnPropertyNames(error), 2)
);

export const formatContext = (context: FormatMessageContextParams): string => {
const { appName, electronProcess, level, network } = context;
return `[${appName}.*${network}*:${level}:${electronProcess}]`;
};

export const formatMessageTime = (date: Date): string => {
const [year, time] = date.toISOString().split('T');
return `[${year}T${time.slice(0, -1)}Z]`;
};

export const constructMessageBody = (bodyData: ConstructMessageBodyParams): MessageBody => {
let messageBody = { ...DEFAULT_MESSAGE_BODY, ...bodyData };
if (typeof messageBody.data === 'string') {
messageBody = { ...messageBody, data: { response: messageBody.data } };
}
const { at, env, ns, data, app, msg, pid, sev, thread } = messageBody;
return { at, env, ns, data, app, msg, pid, sev, thread };
};

export const formatMessage = (loggerMessage: ElectronLoggerMessage): string => {
const at = loggerMessage.date.toISOString();
const [context, messageData] = loggerMessage.data;
const { level } = loggerMessage;
const { message: msg, data = {}, environmentData } = messageData;
const { network, os, platformVersion, version } = environmentData;

const messageBodyParams: ConstructMessageBodyParams = {
at,
env: `${network}:${os}:${platformVersion}`,
ns: [
'daedalus',
`v${version}`,
`*${network}*`,
],
data,
msg,
pid: '',
sev: level,
thread: '',
};

const messageBody: MessageBody = constructMessageBody(messageBodyParams);

if (isProd) return stringifyMessageBody(messageBody);

const messageTime: string = formatMessageTime(loggerMessage.date);
return `${messageTime} ${context} ${stringifyMessageBody(messageBody)}`;
};
Oops, something went wrong.

0 comments on commit 411a09e

Please sign in to comment.