Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

feat: add opencensus-core package #2

Merged
tags07 merged 156 commits intocensus-instrumentation:masterfrom
fabiogomessilva:master
May 1, 2018
Merged

feat: add opencensus-core package #2
tags07 merged 156 commits intocensus-instrumentation:masterfrom
fabiogomessilva:master

Conversation

@fabiogomessilva
Copy link
Copy Markdown
Member

This PR contains opencensus nodejs core package.

The core package includes types and classes for opencensus domain model, exporters, and instrumentations: Span, RootSpan, Tracer, Sampler, Exporters, and Plugins (for instrumentation). Including also the Tracing interface and a default implementation for a logger and a console exporter. Unit tests included.

Opencensus-node packages are managed by Lerna.

@googlebot
Copy link
Copy Markdown

So there's good news and bad news.

👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there.

😕 The bad news is that it appears that one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that here in the pull request.

Note to project maintainer: This is a terminal state, meaning the cla/google commit status will not change from this state. It's up to you to confirm consent of the commit author(s) and merge this pull request when appropriate.

@kjin kjin self-requested a review April 25, 2018 17:21
Copy link
Copy Markdown
Contributor

@kjin kjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you feel that any of these comments should be done in a separate PR, please make a note of that in the form of a TODO comment (so that we can keep track).

Feel free to start a discussion on any comment that you might be confused on or disagree with. If it's not worth creating a full reply, you can comment "done" or use the 👍 reaction to help keep track of which comments have been addressed.

Comment thread package.json Outdated
"author": "Google Inc.",
"license": "Apache-2.0",
"engines": {
"node": ">=6.00"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Remove the extra 0 here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Comment thread README.md Outdated

OpenCensus is a toolkit for collecting application performance and behavior data. It currently
includes 3 apis: stats, tracing and tags.
OpenCensus Node.js is an implementation of OpenCensus, a toolkit for collecting application performance and behavior monitoring data. Right now OpenCensus for Node.js supports custom tracing and automatic tracing for http and mongodb.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few nits:

  • We should be consistent between OpenCensus Node.js and OpenCensus for Node.js (I prefer the latter)
  • Right now -> Currently
  • Codify http and mongodb to suggest that these are modules

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this PR I've simplified even more the README.md text. Even though I didn't add an explicit TODO, obviously it is a TODO for a next PR. Ok?

Comment thread README.md Outdated
- v6.10.0 (for console exporter only)
- v9.8.0 (for Stackdriver and Zipkin exporters)

___
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Remove underlines

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Comment thread package.json Outdated
"version": "0.0.1",
"description": "OpenCensus is a toolkit for collecting application performance and behavior data.",
"main": "build/src/index.js",
"types": "build/src/index.d.js",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

index.d.ts

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Comment thread packages/opencensus-core/AUTHORS Outdated
@@ -0,0 +1 @@
Google Inc. No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be OpenCensus Authors?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should add CESAR to this list and/or individual contributors

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should add CESAR to this list and/or individual contributors


const tracer = new Tracer();

describe('Span', () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to merge similar tests between RootSpan and Span? You can do so in a follow-up PR if needed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO. We gonna evaluate that.

describe('get active()', () => {
let tracer: Tracer;
before(() => {
tracer = new Tracer();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add an assertion here to ensure that it wasn't active beforehand.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done !

});

/** Should return a started tracer instance */
describe('start()', () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test seems nearly identical to get active().

Copy link
Copy Markdown
Member Author

@fabiogomessilva fabiogomessilva Apr 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test case for get active() was removed.

});


/** Testing void functions */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are these cases testing?

Copy link
Copy Markdown
Member Author

@fabiogomessilva fabiogomessilva Apr 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test cases for tracer were updated.

Comment thread packages/opencensus-core/tsconfig.json Outdated
"sourceMap": false
},
"include": [
"src/*.ts",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be "src/**/*.ts" or npm run fix will not work.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@fabiogomessilva fabiogomessilva force-pushed the master branch 2 times, most recently from 1efd7e5 to 5ba700f Compare April 30, 2018 10:26
logger['logger'] = defaultLogger;
return defaultLogger;
};
const logger = (options?: types.LoggerOptions|string|number) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to allow options to be a number? LoggerOptions only accepts the logging level as a string.

Copy link
Copy Markdown
Member Author

@fabiogomessilva fabiogomessilva Apr 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logLevel is a number in Config interface. So, we decide to keep the logic to convert logLevel numbers to string in that class. I will add a TODO for reevaluation.


logger();
const aLogger = new ConsoleLogger(opt);
logger['logger'] = aLogger;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you call logger() multiple times, you get different loggers. If that is desired, I don't see why you need to store the logger on the ['logger'] property. If that is not desired, you should add something like if (logger['logger']) {...} to avoid re-creating the object each time.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we always return the same logger instance, will not be possible to have loggers with different log levels at the same time, what can limit some test capability. I will add a TODO for reevaluation.

* @param name The function name.
* @param wrapper The wrapper.
*/
protected wrap(nodule, name, wrapper) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's OK for instrumentations to depend on shimmer since npm will install a single module for all of them anyway, so there is no dependency size penalty. I would still prefer to keep the API as minimal as possible, especially functions like these that are little more than call-throughs to an underlying dependency module.

* @param parentSpanId The parent span ID.
*/
startSpan(name?: string, type?: string, parentSpanId?: string): types.Span {
startChildSpan(name?: string, type?: string, parentSpanId?: string):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe parentSpanId doesn't need to be here? It's guaranteed to be this.spanId.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree.


/** Gives the TraceContext of the span. */
get traceContext(): types.TraceContext {
get spanContext(): types.SpanContext {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was the type/field changed to SpanContext? I thought TraceContext was fine. (If you decide to keep SpanContext, please change the code comment above.)

Actually, also looking at this more closely -- does the parentSpanId need to be there? It's not part of the SpanContext interface. Also, it would be great to have options here as well.

Copy link
Copy Markdown
Member Author

@fabiogomessilva fabiogomessilva Apr 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was the type/field changed to SpanContext?

It was changed to be consistent with opencensus that uses the term SpanContext:
https://github.com/census-instrumentation/opencensus-java/blob/master/api/src/main/java/io/opencensus/trace/SpanContext.java

Actually, also looking at this more closely -- does the parentSpanId need to be there?

There is no parentSpanId in opencensus SpanContext interface. As I understand the spanId should represent a parendSpanID when the context is propagated.

/**
* This class represent a tracer.
*/
export class Tracer implements types.Tracer {
Copy link
Copy Markdown
Contributor

@kjin kjin Apr 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea to keep types depending on types and not on concrete implementations.

Generally, I agree. However it depends on the use case. In my mind there are two reasons for a dependent module to use a type definition -- either to extend it, or to instantiate/handle objects of that type. Interfaces like Exporter, Plugin, Logger, and so on are meant to extended by other modules, while Tracer falls in the latter category of being used by other modules, but not extended. That's why I believe that exporters, plugins, etc should be interfaces while Tracer should be a single class.

As we discussed in person, we should consider in the future whether there needs to be a specific interface for Tracer. Keep in mind that type definitions exported by this module don't contain any implementations whatsoever anyway, so other modules will always depend on types only and not implementations. The difference is whether the type definitions will say interface Tracer ... class Tracer or just class Tracer.

import {Logger} from '../src/common/types';
import {Buffer} from '../src/exporters/buffer';
import {ConsoleExporter} from '../src/exporters/console-exporter';
import {ExporterBuffer} from '../src/exporters/exporter-buffer';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Remove unused imports

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

describe('setBufferSize', () => {
it('should set BufferSize', () => {
const buffer = new ExporterBuffer(exporter, defaultBufferConfig);
const bufferResize = buffer.setBufferSize(DEFAULT_BUFFER_SIZE);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest using a value here other than DEFAULT_BUFFER_SIZE.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

assert.strictEqual(sampler.description, 'always');
assert.ok(samplerShouldSampler);
});
it('should return a always sampler', () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use different test case messages for these two tests (same for never sampler)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

} as types.SpanContext;


it('should reate the new RootSpan with propagation', () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: create

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Copy link
Copy Markdown
Contributor

@kjin kjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks mostly good to me -- I added a few final comments. Once you've addressed them we should be good to merge.

Comment thread packages/opencensus-core/package.json Outdated
"nyc": "11.6.0"
},
"dependencies": {
"async_hooks": "^1.0.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like it wasn't removed? Did I miss something?

}
}
const aRoot = new RootSpan(this, options);
const sampleDecisition: boolean = propagatedSample ?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sampleDecisition -> sampleDecision

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@@ -0,0 +1,100 @@
/**
* Copyright 2018 Google LLC. All Rights Reserved.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change copyright here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@tags07 tags07 merged commit 67860ba into census-instrumentation:master May 1, 2018
tags07 added a commit that referenced this pull request May 1, 2018
justindsmith pushed a commit to justindsmith/opencensus-node that referenced this pull request Aug 15, 2018
The JaegerTraceExporterOptions accepts `tags` as a Tag array, but was
processing those tags for the process information as if they were an object /
Record instead of a Tag array. This was leading to the process key-value
inside Jaeger to be the array index as key and the value as the key-value
object. We now use the proper key-value information from the input to place
into the process tags.

There were two approaches we could have taken here: 1. To leave the input
as a Tag array and process the input properly in the code or 2. To change
the input to a key-value record / object (Record<string, TagValue), which
would be handled properly by the existing code. We have chosen approach census-instrumentation#1
because a Jaeger process tag CAN support multiple tags with the same key
name, which would not be supported in approach census-instrumentation#2. There is a chance that
(because we were not previously exporting typescript types) users were
passing in a Record format instead of Array, and thus this might be seen
as a breaking change.

A test has been added to validate the process information to ensure proper
format.

Also included are sticter typing for all thrift types, removing all `any`
references and replacing with valid types.
kjin pushed a commit that referenced this pull request Aug 17, 2018
The JaegerTraceExporterOptions accepts `tags` as a Tag array, but was
processing those tags for the process information as if they were an object /
Record instead of a Tag array. This was leading to the process key-value
inside Jaeger to be the array index as key and the value as the key-value
object. We now use the proper key-value information from the input to place
into the process tags.

There were two approaches we could have taken here: 1. To leave the input
as a Tag array and process the input properly in the code or 2. To change
the input to a key-value record / object (Record<string, TagValue), which
would be handled properly by the existing code. We have chosen approach #1
because a Jaeger process tag CAN support multiple tags with the same key
name, which would not be supported in approach #2. There is a chance that
(because we were not previously exporting typescript types) users were
passing in a Record format instead of Array, and thus this might be seen
as a breaking change.

A test has been added to validate the process information to ensure proper
format.

Also included are sticter typing for all thrift types, removing all `any`
references and replacing with valid types.
kjin pushed a commit to kjin/opencensus-node that referenced this pull request Aug 24, 2018
…on#93)

The JaegerTraceExporterOptions accepts `tags` as a Tag array, but was
processing those tags for the process information as if they were an object /
Record instead of a Tag array. This was leading to the process key-value
inside Jaeger to be the array index as key and the value as the key-value
object. We now use the proper key-value information from the input to place
into the process tags.

There were two approaches we could have taken here: 1. To leave the input
as a Tag array and process the input properly in the code or 2. To change
the input to a key-value record / object (Record<string, TagValue), which
would be handled properly by the existing code. We have chosen approach census-instrumentation#1
because a Jaeger process tag CAN support multiple tags with the same key
name, which would not be supported in approach census-instrumentation#2. There is a chance that
(because we were not previously exporting typescript types) users were
passing in a Record format instead of Array, and thus this might be seen
as a breaking change.

A test has been added to validate the process information to ensure proper
format.

Also included are sticter typing for all thrift types, removing all `any`
references and replacing with valid types.
kjin pushed a commit to kjin/opencensus-node that referenced this pull request Aug 24, 2018
…on#93)

The JaegerTraceExporterOptions accepts `tags` as a Tag array, but was
processing those tags for the process information as if they were an object /
Record instead of a Tag array. This was leading to the process key-value
inside Jaeger to be the array index as key and the value as the key-value
object. We now use the proper key-value information from the input to place
into the process tags.

There were two approaches we could have taken here: 1. To leave the input
as a Tag array and process the input properly in the code or 2. To change
the input to a key-value record / object (Record<string, TagValue), which
would be handled properly by the existing code. We have chosen approach census-instrumentation#1
because a Jaeger process tag CAN support multiple tags with the same key
name, which would not be supported in approach census-instrumentation#2. There is a chance that
(because we were not previously exporting typescript types) users were
passing in a Record format instead of Array, and thus this might be seen
as a breaking change.

A test has been added to validate the process information to ensure proper
format.

Also included are sticter typing for all thrift types, removing all `any`
references and replacing with valid types.
kjin pushed a commit to kjin/opencensus-node that referenced this pull request Aug 24, 2018
…on#93)

The JaegerTraceExporterOptions accepts `tags` as a Tag array, but was
processing those tags for the process information as if they were an object /
Record instead of a Tag array. This was leading to the process key-value
inside Jaeger to be the array index as key and the value as the key-value
object. We now use the proper key-value information from the input to place
into the process tags.

There were two approaches we could have taken here: 1. To leave the input
as a Tag array and process the input properly in the code or 2. To change
the input to a key-value record / object (Record<string, TagValue), which
would be handled properly by the existing code. We have chosen approach census-instrumentation#1
because a Jaeger process tag CAN support multiple tags with the same key
name, which would not be supported in approach census-instrumentation#2. There is a chance that
(because we were not previously exporting typescript types) users were
passing in a Record format instead of Array, and thus this might be seen
as a breaking change.

A test has been added to validate the process information to ensure proper
format.

Also included are sticter typing for all thrift types, removing all `any`
references and replacing with valid types.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants