Faster trace id generation (#824)

This commit is contained in:
Daniel Dyla 2020-03-03 16:14:48 -05:00 committed by GitHub
parent 86ce078558
commit 5a5b6b8ffe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 16 deletions

View File

@ -21,24 +21,38 @@ declare type WindowWithMsCrypto = Window & {
const cryptoLib = window.crypto || (window as WindowWithMsCrypto).msCrypto;
const SPAN_ID_BYTES = 8;
const spanBytesArray = new Uint8Array(SPAN_ID_BYTES);
const TRACE_ID_BYTES = 16;
const randomBytesArray = new Uint8Array(TRACE_ID_BYTES);
/** Returns a random 16-byte trace ID formatted as a 32-char hex string. */
export function randomTraceId(): string {
return randomSpanId() + randomSpanId();
cryptoLib.getRandomValues(randomBytesArray);
return toHex(randomBytesArray.slice(0, TRACE_ID_BYTES));
}
/** Returns a random 8-byte span ID formatted as a 16-char hex string. */
export function randomSpanId(): string {
let spanId = '';
cryptoLib.getRandomValues(spanBytesArray);
for (let i = 0; i < SPAN_ID_BYTES; i++) {
const hexStr = spanBytesArray[i].toString(16);
// Zero pad bytes whose hex values are single digit.
if (hexStr.length === 1) spanId += '0';
spanId += hexStr;
}
return spanId;
cryptoLib.getRandomValues(randomBytesArray);
return toHex(randomBytesArray.slice(0, SPAN_ID_BYTES));
}
/**
* Get the hex string representation of a byte array
*
* @param byteArray
*/
function toHex(byteArray: Uint8Array) {
const chars: number[] = new Array(byteArray.length * 2);
const alpha = 'a'.charCodeAt(0) - 10;
const digit = '0'.charCodeAt(0);
let p = 0;
for (let i = 0; i < byteArray.length; i++) {
let nibble = (byteArray[i] >>> 4) & 0xf;
chars[p++] = nibble > 9 ? nibble + alpha : nibble + digit;
nibble = byteArray[i] & 0xf;
chars[p++] = nibble > 9 ? nibble + alpha : nibble + digit;
}
return String.fromCharCode.apply(null, chars);
}

View File

@ -17,13 +17,14 @@
import * as crypto from 'crypto';
const SPAN_ID_BYTES = 8;
const TRACE_ID_BYTES = 16;
/**
* Returns a random 16-byte trace ID formatted/encoded as a 32 lowercase hex
* characters corresponding to 128 bits.
*/
export function randomTraceId(): string {
return randomSpanId() + randomSpanId();
return crypto.randomBytes(TRACE_ID_BYTES).toString('hex');
}
/**

View File

@ -18,15 +18,31 @@ import * as assert from 'assert';
import { randomSpanId, randomTraceId } from '../../src/platform';
describe('randomTraceId', () => {
it('returns different 32-char hex strings', () => {
it('returns 32 character hex strings', () => {
const traceId = randomTraceId();
assert.ok(traceId.match(/[a-f0-9]{32}/));
assert.ok(!traceId.match(/^0+$/));
});
it('returns different ids on each call', () => {
const traceId1 = randomTraceId();
const traceId2 = randomTraceId();
assert.notDeepStrictEqual(traceId1, traceId2);
});
});
describe('randomSpanId', () => {
it('returns different 16-char hex string', () => {
it('returns 16 character hex strings', () => {
const spanId = randomSpanId();
assert.ok(spanId.match(/[a-f0-9]{16}/));
assert.ok(!spanId.match(/^0+$/));
});
it('returns different ids on each call', () => {
const spanId1 = randomSpanId();
const spanId2 = randomSpanId();
assert.notDeepStrictEqual(spanId1, spanId2);
});
});