Skip to content

Commit

Permalink
Merge branch 'master' into bluebird-patch
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinBeckwith authored Nov 20, 2018
2 parents 864960d + 2e48c0c commit ccc3c7d
Show file tree
Hide file tree
Showing 43 changed files with 1,334 additions and 880 deletions.
14 changes: 13 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ workflows:
- node6
- node8
- node10
- node11
tests:
jobs:
- node6:
Expand All @@ -98,11 +99,14 @@ workflows:
filters: *release_tags
- node10:
filters: *release_tags
- node11:
filters: *release_tags
- publish_npm:
requires:
- node6
- node8
- node10
- node11
filters:
branches:
ignore: /.*/
Expand Down Expand Up @@ -133,9 +137,17 @@ jobs:
- *postgres_service
- *mysql_service
<<: *unit_tests
node11:
docker:
- image: node:11
- *mongo_service
- *redis_service
- *postgres_service
- *mysql_service
<<: *unit_tests
publish_npm:
docker:
- image: node:8
- image: node:10
user: node
steps:
- checkout
Expand Down
3 changes: 1 addition & 2 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
node_modules/*
samples/node_modules/*
**/node_modules
src/**/doc/*
build/
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ Optionally, you can pass a [configuration object](src/config.ts) to the `start()

```js
require('@google-cloud/trace-agent').start({
samplingRate: 500, // sample one trace every half-second.
samplingRate: 5, // sample 5 traces per second, or at most 1 every 200 milliseconds.
ignoreUrls: [ /^\/ignore-me#/ ] // ignore the "/ignore-me" endpoint.
ignoreMethods: [ 'options' ] // ignore requests with OPTIONS method (case-insensitive).
});
// ...
```
Expand All @@ -59,7 +60,7 @@ The trace agent can do automatic tracing of the following web frameworks:
* [gRPC](https://www.npmjs.com/package/grpc) server (version ^1.1)
* [hapi](https://www.npmjs.com/package/hapi) (versions 8 - 16)
* [koa](https://www.npmjs.com/package/koa) (version 1)
* [restify](https://www.npmjs.com/package/restify) (versions 3 - 6)
* [restify](https://www.npmjs.com/package/restify) (versions 3 - 7)

The agent will also automatically trace RPCs from the following modules:
* Outbound HTTP requests through `http`, `https`, and `http2` core modules
Expand All @@ -68,7 +69,7 @@ The agent will also automatically trace RPCs from the following modules:
* [mongoose](https://www.npmjs.com/package/mongoose) (version 4 - 5)
* [mysql](https://www.npmjs.com/package/mysql) (version ^2.9)
* [mysql2](https://www.npmjs.com/package/mysql2) (version 1)
* [pg](https://www.npmjs.com/package/mysql2) (versions 6 - 7)
* [pg](https://www.npmjs.com/package/pg) (versions 6 - 7)
* [redis](https://www.npmjs.com/package/redis) (versions 0.12 - 2)

You can use the [Custom Tracing API](#custom-tracing-api) to trace other modules in your application.
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@google-cloud/trace-agent",
"version": "3.2.1",
"version": "3.3.1",
"description": "Node.js Support for StackDriver Trace",
"main": "build/src/index.js",
"types": "build/src/index.d.ts",
Expand Down Expand Up @@ -53,7 +53,7 @@
"@types/continuation-local-storage": "^3.2.1",
"@types/extend": "^3.0.0",
"@types/glob": "^7.0.0",
"@types/is": "0.0.20",
"@types/is": "0.0.21",
"@types/methods": "^1.1.0",
"@types/mocha": "^5.2.5",
"@types/ncp": "^2.0.1",
Expand All @@ -73,8 +73,8 @@
"codecov": "^3.0.0",
"express": "^4.15.2",
"glob": "^7.0.3",
"grpc": "1.16.0",
"gts": "^0.8.0",
"grpc": "1.16.1",
"gts": "^0.9.0",
"intelli-espower-loader": "^1.0.1",
"js-green-licenses": "^0.5.0",
"jshint": "^2.9.1",
Expand Down
1 change: 1 addition & 0 deletions samples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.gcloudignore
37 changes: 37 additions & 0 deletions samples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Stackdriver Trace for Node.js Sample Application

This sample demonstrates using [Stackdriver Trace][trace] with Node.js.

> Node 8+ is required for this sample.
* [Setup](#setup)
* [Running locally](#running-locally)
* [Deploying to App Engine](#deploying-to-app-engine)
* [Viewing Traces](#viewing-traces)

## Setup

Before you can run or deploy the sample, you need to do the following:

1. Refer to the [this README file][readme] for instructions on
running and deploying.
1. Install dependencies:

npm install

## Running locally

npm start

## Deploying to App Engine

Ensure that you have an up-to-date `gcloud` (run `gcloud components update`), and then:

npm run deploy

## Viewing Traces

Use the [Stackdriver Trace dashboard](https://console.cloud.google.com/traces/traces) to inspect recorded traces.

[trace]: https://cloud.google.com/trace/
[readme]: https://github.com/GoogleCloudPlatform/nodejs-docs-samples/blob/master/appengine/README.md
57 changes: 57 additions & 0 deletions samples/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Copyright 2017, Google, Inc.
* Licensed 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.
*/

'use strict';

// [START trace_app]
if (process.env.NODE_ENV === 'production') {
// [START trace_setup_implicit]
require('@google-cloud/trace-agent').start();
// [END trace_setup_implicit]
}

const express = require('express');
const got = require('got');

const app = express();
const DISCOVERY_URL = 'https://www.googleapis.com/discovery/v1/apis';

// This incoming HTTP request should be captured by Trace
app.get('/', (req, res) => {
// This outgoing HTTP request should be captured by Trace
got(DISCOVERY_URL, { json: true })
.then((response) => {
const names = response.body.items.map((item) => item.name);

res
.status(200)
.send(names.join('\n'))
.end();
})
.catch((err) => {
console.error(err);
res
.status(500)
.end();
});
});

// Start the server
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
console.log('Press Ctrl+C to quit.');
});
// [END trace_app]
16 changes: 16 additions & 0 deletions samples/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright 2016, Google, Inc.
# Licensed 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.

# [START app_yaml]
runtime: nodejs10
# [END app_yaml]
24 changes: 24 additions & 0 deletions samples/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "cloud-trace-nodejs-samples",
"description": "Sample for Google Stackdriver Trace on Google App Engine Standard Environment.",
"version": "0.0.0",
"private": true,
"license": "Apache-2.0",
"author": "Google Inc.",
"repository": {
"type": "git",
"url": "https://github.com/googleapis/cloud-trace-nodejs.git"
},
"engines": {
"node": ">=8"
},
"scripts": {
"deploy": "gcloud app deploy",
"start": "node app.js"
},
"dependencies": {
"@google-cloud/trace-agent": "^3.3.1",
"express": "^4.16.4",
"got": "^9.3.2"
}
}
23 changes: 23 additions & 0 deletions samples/snippets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Copyright 2017, Google, Inc.
* Licensed 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.
*/

'use strict';

// [START trace_setup_explicit]
require('@google-cloud/trace-agent').start({
projectId: 'your-project-id',
keyFilename: '/path/to/key.json'
});
// [END trace_setup_explicit]
5 changes: 3 additions & 2 deletions scripts/check-install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ export async function checkInstall() {
});
// Install the tgz file as a package, along with necessities.
// @types/node version should match the current process version, but clamped
// at >=9 (because of http2 types).
const nodeTypesVersion = Math.max(getNodeMajorVersion(), 9);
// at >=9 (because of http2 types) and <11 (because Node 11 doesn't yet have
// type definitions).
const nodeTypesVersion = Math.min(Math.max(getNodeMajorVersion(), 9), 10);
await spawnP('npm', ['install', 'typescript', `@types/node@${nodeTypesVersion}`, tgz[0]], {
cwd: installDir
});
Expand Down
32 changes: 25 additions & 7 deletions src/cls/async-hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,17 @@ export class AsyncHooksCLS<Context extends {}> implements CLS<Context> {
// init is called when a new AsyncResource is created. We want code
// that runs within the scope of this new AsyncResource to see the same
// context as its "parent" AsyncResource. The criteria for the parent
// depends on the type of the AsyncResource.
// depends on the type of the AsyncResource. (If the parent doesn't have
// an associated context, don't do anything.)
if (type === 'PROMISE') {
// Opt not to use the trigger ID for Promises, as this causes context
// confusion in applications using async/await.
// Instead, use the ID of the AsyncResource in whose scope we are
// currently running.
this.contexts[id] = this.contexts[this.ah.executionAsyncId()];
const currentId = this.ah.executionAsyncId();
if (this.contexts[currentId] !== undefined) {
this.contexts[id] = this.contexts[currentId];
}
} else {
// Use the trigger ID for any other type. In Node core, this is
// usually equal the ID of the AsyncResource in whose scope we are
Expand All @@ -75,17 +79,31 @@ export class AsyncHooksCLS<Context extends {}> implements CLS<Context> {
// AsyncResource API, because users of that API can specify their own
// trigger ID. In this case, we choose to respect the user's
// selection.
this.contexts[id] = this.contexts[triggerId];
if (this.contexts[triggerId] !== undefined) {
this.contexts[id] = this.contexts[triggerId];
}
}
// Note that this function always assigns values in this.contexts to
// values under other keys, which may or may not be undefined. Consumers
// of the CLS API will get the sentinel (default) value if they query
// the current context when it is stored as undefined.
// Note that this function only assigns values in this.contexts to
// values under other keys; it never generates new context values.
// Consumers of the CLS API will get the sentinel (default) value if
// they query the current context when it is not stored in
// this.contexts.
},
destroy: (id: number) => {
// destroy is called when the AsyncResource is no longer used, so also
// delete its entry in the map.
delete this.contexts[id];
},
promiseResolve: (id: number) => {
// Promise async resources may not get their destroy hook entered for
// a long time, so we listen on promiseResolve hooks as well. If this
// event is emitted, the async scope of the Promise will not be entered
// again, so it is generally safe to delete its entry in the map. (There
// is a possibility that a future async resource will directly reference
// this Promise as its trigger parent -- in this case, it will have
// the wrong parent, but this is still better than a potential memory
// leak.)
delete this.contexts[id];
}
});
}
Expand Down
Loading

0 comments on commit ccc3c7d

Please sign in to comment.