Skip to content

Commit

Permalink
feat(mockotlpserver): some improvements to "summary" styling (#459)
Browse files Browse the repository at this point in the history
- Show attributes for histogram metrics and handle showing multiple data points.
- Bold "span", "event", "$metricType" in renderings; and style the name of that
  span/event/metric in magenta. See PR for screenshots.
  • Loading branch information
trentm authored Dec 12, 2024
1 parent 3ce6cba commit 441bfd0
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 59 deletions.
4 changes: 4 additions & 0 deletions packages/mockotlpserver/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

- feat: Some improvements to "summary" styling.
- Show attributes for histogram metrics and handle showing multiple data points.
- Bold "span", "event", "$metricType" in renderings, and style the name of that
span/event/metric in magenta. See PR for screenshots.
- fix: Don't throw printing a metrics summary for a histogram without attributes.

## v0.5.0
Expand Down
41 changes: 5 additions & 36 deletions packages/mockotlpserver/lib/logs-summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,38 +27,7 @@ const {hrTimeToTimeStamp, millisToHrTime} = require('@opentelemetry/core');

const {Printer} = require('./printers');
const {normalizeLogs} = require('./normalize');

// This color-related block from Bunyan, with permission. ;)
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
// Suggested colors (some are unreadable in common cases):
// - Good: cyan, yellow (limited use), bold, green, magenta, red
// - Bad: blue (not visible on cmd.exe), grey (same color as background on
// Solarized Dark theme from <https://github.com/altercation/solarized>, see
// issue #160)
var colors = {
bold: [1, 22],
italic: [3, 23],
underline: [4, 24],
inverse: [7, 27],
white: [37, 39],
grey: [90, 39],
black: [30, 39],
blue: [34, 39],
cyan: [36, 39],
green: [32, 39],
magenta: [35, 39],
red: [31, 39],
yellow: [33, 39],
};
function stylizeWithColor(str, color) {
if (!str) return '';
var codes = colors[color];
if (codes) {
return '\x1b[' + codes[0] + 'm' + str + '\x1b[' + codes[1] + 'm';
} else {
return str;
}
}
const {style} = require('./styling');

class LogsSummaryPrinter extends Printer {
/**
Expand Down Expand Up @@ -107,15 +76,15 @@ class LogsSummaryPrinter extends Printer {
let lead = `[${time}] ${sev} (${meta}):`;
let bodyInLead = false;
if (isEvent) {
lead += ` Event ${stylizeWithColor(
lead += ` ${style('event', 'bold')} "${style(
rec.attributes['event.name'],
'magenta'
)}`;
)}"`;
} else if (
typeof rec.body === 'string' &&
rec.body.indexOf('\n') === -1
) {
lead += ' ' + stylizeWithColor(rec.body, 'cyan');
lead += ' ' + style(rec.body, 'cyan');
bodyInLead = true;
}
rendering.push(lead);
Expand All @@ -125,7 +94,7 @@ class LogsSummaryPrinter extends Printer {
// pass
} else if (typeof rec.body === 'string') {
rendering.push(
stylizeWithColor(
style(
' ' + rec.body.split(/\n/).join('\n '),
'cyan'
)
Expand Down
59 changes: 37 additions & 22 deletions packages/mockotlpserver/lib/metrics-summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
* Dev Notes / Ideas:
*/

const util = require('util');

const {Printer} = require('./printers');
const {normalizeMetrics} = require('./normalize');
const {style} = require('./styling');

class MetricsSummaryPrinter extends Printer {
printMetrics(rawMetrics) {
Expand All @@ -41,34 +44,46 @@ class MetricsSummaryPrinter extends Printer {
scopes.push(scope);
for (let metric of scopeMetric.metrics) {
if (metric.histogram) {
// TODO do we want to attempt a short summary of histogram buckets?
// TODO handle multiple datapoints, dp per normalized attribute set. Highest prio. Run `node -r @elastic/opentelemetry-node http-server.js` for example data.
if (metric.histogram.dataPoints.length !== 1) {
this._log.warn(
{metric},
'metric has other than 1 dataPoint'
);
rendering.push(` ${metric.name} (histogram)`);
} else {
const dp = metric.histogram.dataPoints[0];
const extras = ['histogram'];
if (metric.unit) {
extras.push(metric.unit);
}
if (dp.attributes) {
extras.push(
`${Object.keys(dp.attributes).length} attrs`
);
// histogram "${name}" (unit=${unit})
// ${metricValueRepr} | <-- one for each data point
// ${attrsRepr} |
// --
// ${metricValueRepr}
// ${attrsRepr}
rendering.push(
`${style('histogram', 'bold')} "${style(
metric.name,
'magenta'
)}" (unit=${metric.unit})`
);
for (
let i = 0;
i < metric.histogram.dataPoints.length;
i++
) {
if (i > 0) {
rendering.push(' --');
}
const dp = metric.histogram.dataPoints[i];
// TODO: consider a meaningful repr of the histogram buckets
rendering.push(
` ${metric.name} (${extras.join(
', '
)}): min=${dp.min}, max=${dp.max}`
` count=${dp.count}, min=${dp.min}, max=${dp.max}`
);
if (
dp.attributes &&
Object.keys(dp.attributes).length > 0
) {
let attrSummary = util.inspect(dp.attributes, {
depth: 10,
colors: true,
breakLength: Infinity,
});
rendering.push(' ' + attrSummary);
}
}
} else {
// TODO handle other metric types better
rendering.push(` ${metric.name} (type=???)`);
rendering.push(`metricType??? "${metric.name}"`);
}
}
}
Expand Down
54 changes: 54 additions & 0 deletions packages/mockotlpserver/lib/styling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// This color-related block from Bunyan, with permission. ;)
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
// Suggested colors (some are unreadable in common cases):
// - Good: cyan, yellow (limited use), bold, green, magenta, red
// - Bad: blue (not visible on cmd.exe), grey (same color as background on
// Solarized Dark theme from <https://github.com/altercation/solarized>, see
// issue #160)
var colors = {
bold: [1, 22],
italic: [3, 23],
underline: [4, 24],
inverse: [7, 27],
white: [37, 39],
grey: [90, 39],
black: [30, 39],
blue: [34, 39],
cyan: [36, 39],
green: [32, 39],
magenta: [35, 39],
red: [31, 39],
yellow: [33, 39],
};
function stylizeWithColor(str, color) {
if (!str) return '';
var codes = colors[color];
if (codes) {
return '\x1b[' + codes[0] + 'm' + str + '\x1b[' + codes[1] + 'm';
} else {
return str;
}
}

module.exports = {
style: stylizeWithColor,
};
5 changes: 4 additions & 1 deletion packages/mockotlpserver/lib/waterfall.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

const {Printer} = require('./printers');
const {jsonStringifyTrace} = require('./normalize');
const {style} = require('./styling');

/*
Expand Down Expand Up @@ -100,7 +101,9 @@ function renderSpan(span, prefix = '') {
gutter = ' '.repeat(6);
}

let r = `${gutter} ${prefix}span ${shortId(span.spanId)} "${span.name}"`;
let r = `${gutter} ${prefix}${style('span', 'bold')} ${shortId(
span.spanId
)} "${style(span.name, 'magenta')}"`;

const extras = [];

Expand Down

0 comments on commit 441bfd0

Please sign in to comment.