Skip to content

Commit

Permalink
address mathieu comments 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
usmanmani1122 committed Oct 24, 2024
1 parent 14deff7 commit 638d536
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 183 deletions.
271 changes: 88 additions & 183 deletions packages/telemetry/src/context-aware-slog.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
/* eslint-env node */
import { logs, SeverityNumber } from '@opentelemetry/api-logs';
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
import { Resource } from '@opentelemetry/resources';
import {
LoggerProvider,
SimpleLogRecordProcessor,
} from '@opentelemetry/sdk-logs';
import { readFileSync, writeFileSync } from 'fs';
import { dirSync } from 'tmp';
import { getResourceAttributes } from './index.js';

/**
* @typedef {Partial<{
Expand Down Expand Up @@ -39,8 +29,6 @@ import { getResourceAttributes } from './index.js';
* timestamp: Slog['time'];
* } & Context} LogAttributes
*
* @typedef {{env: typeof process.env; stateDir: string;}} Options
*
* @typedef {{
* blockHeight?: number;
* blockTime?: number;
Expand All @@ -60,8 +48,6 @@ import { getResourceAttributes } from './index.js';
* }} Slog
*/

const FILE_ENCODING = 'utf8';

const SLOG_TYPES = {
CLIST: 'clist',
CONSOLE: 'console',
Expand Down Expand Up @@ -109,49 +95,11 @@ const SLOG_TYPES = {
};

/**
* @param {string} filePath
* @param {(log: { attributes: LogAttributes, body: Partial<Slog> }) => void} emitLog
* @param {Partial<{ persistContext: (context: Context) => void; restoreContext: () => Context | null; }>?} persistenceUtils
*/
export const getContextFilePersistenceUtils = filePath => {
console.log(`Using file ${filePath} for slogger`);

return {
/**
* @param {Context} context
*/
persistContext: context => {
try {
writeFileSync(filePath, JSON.stringify(context), FILE_ENCODING);
} catch (err) {
console.warn('Error writing context to file: ', err);
}
},

/**
* @returns {Context | null}
*/
restoreContext: () => {
try {
return JSON.parse(readFileSync(filePath, FILE_ENCODING));
} catch (parseErr) {
console.warn('Error reading context from file: ', parseErr);
return null;
}
},
};
};

const stringify = data =>
JSON.stringify(data, (_, value) =>
typeof value === 'bigint' ? Number(value) : value,
);

/**
* @param {(log: import('@opentelemetry/api-logs').LogRecord) => void} emitLog
* @param {Options} options
* @param {Partial<{ persistContext: (context: Context) => void; restoreContext: () => Context | null; }>} persistenceUtils
*/
export const logCreator = (emitLog, options, persistenceUtils) => {
const { CHAIN_ID } = options.env;
export const logCreator = (emitLog, persistenceUtils = {}) => {
const { CHAIN_ID } = process.env;

/** @type Array<Context | null> */
let [
Expand All @@ -168,19 +116,20 @@ export const logCreator = (emitLog, options, persistenceUtils) => {
*/
const persistContext = context => {
lastPersistedTriggerContext = context;
return persistenceUtils.persistContext?.(context);
return persistenceUtils?.persistContext?.(context);
};

const restoreContext = () => {
if (!lastPersistedTriggerContext)
lastPersistedTriggerContext = persistenceUtils.restoreContext?.() || null;
lastPersistedTriggerContext =
persistenceUtils?.restoreContext?.() || null;
return lastPersistedTriggerContext;
};

/**
* @param {Slog} slog
*/
const slogSender = ({ monotime, time: timestamp, ...body }) => {
const slogProcessor = ({ monotime, time: timestamp, ...body }) => {
const finalBody = { ...body };

/** @type {{'crank.syscallNum'?: Slog['syscallNum']}} */
Expand All @@ -191,75 +140,31 @@ export const logCreator = (emitLog, options, persistenceUtils) => {
* like setting context data
*/
switch (body.type) {
case SLOG_TYPES.CONSOLE: {
delete finalBody.crankNum;
delete finalBody.deliveryNum;

break;
}
case SLOG_TYPES.CLIST: {
assert(!!crankContext);
crankContext['crank.vatID'] = finalBody.vatID;
break;
}
case SLOG_TYPES.CRANK.START: {
crankContext = {
'crank.num': finalBody.crankNum,
'crank.type': finalBody.crankType,
};
break;
}
case SLOG_TYPES.DELIVER: {
if (replayContext) {
assert(finalBody.replay);
replayContext = {
...replayContext,
'crank.deliveryNum': finalBody.deliveryNum,
'crank.vatID': finalBody.vatID,
};
} else {
assert(!!crankContext && !finalBody.replay);
crankContext = {
...crankContext,
'crank.deliveryNum': finalBody.deliveryNum,
'crank.vatID': finalBody.vatID,
};
}

delete finalBody.deliveryNum;
delete finalBody.replay;

break;
}
case SLOG_TYPES.DELIVER_RESULT: {
delete finalBody.deliveryNum;
delete finalBody.replay;

break;
}
case SLOG_TYPES.KERNEL.INIT.START: {
initContext = { init: true };
break;
}
case SLOG_TYPES.REPLAY.START: {
replayContext = { replay: true };
break;
}
case SLOG_TYPES.COSMIC_SWINGSET.AFTER_COMMIT_STATS: {
assert(!!blockContext);
break;
}
case SLOG_TYPES.COSMIC_SWINGSET.BEGIN_BLOCK: {
blockContext = {
'block.height': finalBody.blockHeight,
'block.time': finalBody.blockTime,
};
break;
}
case SLOG_TYPES.COSMIC_SWINGSET.BOOTSTRAP_BLOCK.FINISH: {
case SLOG_TYPES.COSMIC_SWINGSET.END_BLOCK.START: {
assert(!!blockContext);
break;
}
case SLOG_TYPES.COSMIC_SWINGSET.END_BLOCK.FINISH:
case SLOG_TYPES.COSMIC_SWINGSET.COMMIT.START:
case SLOG_TYPES.COSMIC_SWINGSET.COMMIT.FINISH: {
assert(!!blockContext);
break;
}
case SLOG_TYPES.COSMIC_SWINGSET.AFTER_COMMIT_STATS: {
assert(!!blockContext && !triggerContext);
break;
}
case SLOG_TYPES.COSMIC_SWINGSET.BOOTSTRAP_BLOCK.START: {
blockContext = {
'block.height': finalBody.blockHeight || 0,
Expand All @@ -273,6 +178,10 @@ export const logCreator = (emitLog, options, persistenceUtils) => {
};
break;
}
case SLOG_TYPES.COSMIC_SWINGSET.BOOTSTRAP_BLOCK.FINISH: {
assert(!!blockContext && !triggerContext);
break;
}
case SLOG_TYPES.COSMIC_SWINGSET.BRIDGE_INBOUND:
case SLOG_TYPES.COSMIC_SWINGSET.DELIVER_INBOUND: {
const [blockHeight, txHash, msgIdx] = (
Expand All @@ -294,16 +203,6 @@ export const logCreator = (emitLog, options, persistenceUtils) => {
persistContext(triggerContext);
break;
}
case SLOG_TYPES.COSMIC_SWINGSET.COMMIT.FINISH:
case SLOG_TYPES.COSMIC_SWINGSET.COMMIT.START:
case SLOG_TYPES.COSMIC_SWINGSET.END_BLOCK.FINISH: {
assert(!!blockContext);
break;
}
case SLOG_TYPES.COSMIC_SWINGSET.END_BLOCK.START: {
assert(!!blockContext);
break;
}
// eslint-disable-next-line no-restricted-syntax
case SLOG_TYPES.COSMIC_SWINGSET.RUN.START: {
if (!triggerContext && finalBody.runNum !== 0) {
Expand All @@ -323,6 +222,50 @@ export const logCreator = (emitLog, options, persistenceUtils) => {

break;
}
case SLOG_TYPES.CRANK.START: {
crankContext = {
'crank.num': finalBody.crankNum,
'crank.type': finalBody.crankType,
};
break;
}
case SLOG_TYPES.CLIST: {
assert(!!crankContext);
crankContext['crank.vatID'] = finalBody.vatID;
break;
}
case SLOG_TYPES.REPLAY.START: {
replayContext = { replay: true };
break;
}
case SLOG_TYPES.DELIVER: {
if (replayContext) {
assert(finalBody.replay);
replayContext = {
...replayContext,
'crank.deliveryNum': finalBody.deliveryNum,
'crank.vatID': finalBody.vatID,
};
} else {
assert(!!crankContext && !finalBody.replay);
crankContext = {
...crankContext,
'crank.deliveryNum': finalBody.deliveryNum,
'crank.vatID': finalBody.vatID,
};
}

delete finalBody.deliveryNum;
delete finalBody.replay;

break;
}
case SLOG_TYPES.DELIVER_RESULT: {
delete finalBody.deliveryNum;
delete finalBody.replay;

break;
}
case SLOG_TYPES.SYSCALL:
case SLOG_TYPES.SYSCALL_RESULT: {
eventLogAttributes['crank.syscallNum'] = finalBody.syscallNum;
Expand All @@ -333,6 +276,12 @@ export const logCreator = (emitLog, options, persistenceUtils) => {

break;
}
case SLOG_TYPES.CONSOLE: {
delete finalBody.crankNum;
delete finalBody.deliveryNum;

break;
}
default:
// All other log types are logged as is (using existing contexts) without
// any change to the slogs or any contributions to the contexts. This also
Expand All @@ -355,32 +304,19 @@ export const logCreator = (emitLog, options, persistenceUtils) => {
timestamp,
};

emitLog({
attributes: JSON.parse(stringify(logAttributes)),
body: JSON.parse(stringify(finalBody)),
severityNumber: SeverityNumber.INFO,
});
emitLog({ attributes: logAttributes, body: finalBody });

/**
* Add any after report operations here
* like resetting context data
*/
switch (body.type) {
case SLOG_TYPES.CRANK.RESULT: {
crankContext = null;
break;
}
case SLOG_TYPES.KERNEL.INIT.FINISH: {
initContext = null;
break;
}
case SLOG_TYPES.REPLAY.FINISH: {
replayContext = null;
break;
}
// eslint-disable-next-line no-restricted-syntax
case SLOG_TYPES.COSMIC_SWINGSET.RUN.FINISH: {
triggerContext = null;
case SLOG_TYPES.COSMIC_SWINGSET.END_BLOCK.START: {
triggerContext = restoreContext();
break;
}
case SLOG_TYPES.COSMIC_SWINGSET.AFTER_COMMIT_STATS: {
Expand All @@ -391,54 +327,23 @@ export const logCreator = (emitLog, options, persistenceUtils) => {
blockContext = null;
break;
}
case SLOG_TYPES.COSMIC_SWINGSET.END_BLOCK.START: {
triggerContext = restoreContext();
// eslint-disable-next-line no-restricted-syntax
case SLOG_TYPES.COSMIC_SWINGSET.RUN.FINISH: {
triggerContext = null;
break;
}
case SLOG_TYPES.CRANK.RESULT: {
crankContext = null;
break;
}
case SLOG_TYPES.REPLAY.FINISH: {
replayContext = null;
break;
}
default:
break;
}
};

return slogSender;
};

/**
* @param {Options} options
*/
export const makeSlogSender = options => {
const { OTEL_EXPORTER_OTLP_ENDPOINT } = options.env;
if (!OTEL_EXPORTER_OTLP_ENDPOINT)
return console.warn(
'Ignoring invocation of slogger "context-aware-slog" without the presence of "OTEL_EXPORTER_OTLP_ENDPOINT" envrionment variable',
);

const loggerProvider = new LoggerProvider({
resource: new Resource(getResourceAttributes(options)),
});
const logRecordProcessor = new SimpleLogRecordProcessor(
new OTLPLogExporter({ keepAlive: true }),
);

loggerProvider.addLogRecordProcessor(logRecordProcessor);

logs.setGlobalLoggerProvider(loggerProvider);
const logger = logs.getLogger('default');

const persistenceUtils = getContextFilePersistenceUtils(
process.env.SLOG_CONTEXT_FILE_PATH ||
`${options.stateDir || dirSync({ prefix: 'slog-context' }).name}/slog-context.json`,
);

const slogSender = logCreator(
logRecord => logger.emit(logRecord),
options,
persistenceUtils,
);

return Object.assign(slogSender, {
forceFlush: () => logRecordProcessor.forceFlush(),
shutdown: () =>
logRecordProcessor.forceFlush().then(logRecordProcessor.shutdown),
});
return slogProcessor;
};
Loading

0 comments on commit 638d536

Please sign in to comment.