Socket
Socket
Sign inDemoInstall

@newrelic/aws-sdk

Package Overview
Dependencies
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@newrelic/aws-sdk - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

14

CHANGELOG.md

@@ -0,2 +1,16 @@

### 0.3.0 (2019-07-18):
* Adds support for DocumentClient API calls to be captured as Datastore segments/metrics.
Supported calls are: `get`, `put`, `update`, `delete`, `query` and `scan`. These will be named according to the underlying DynamoDB operation that is executed. For example: `get` will be named `getItem`. DocumentClient calls not listed above will still be captured as Externals.
* Fixed issue that would prevent multiple DynamoDB instances from being instrumented.
* Replaced `database_name` with `collection` in DynamoDB attributes.
* Moved `name` property to the root of DynamoDB segment description object.
Previously, segments were being incorrectly named `"Datastore/operation/DynamoDB/undefined"`, due to the operation name being misplaced.
### 0.2.0 (2019-02-19):

@@ -3,0 +17,0 @@

57

lib/dynamodb.js
'use strict'
const OPERATIONS = [
const DDB_OPERATIONS = [
'putItem',

@@ -14,23 +14,29 @@ 'getItem',

let dynamoProtoWrapped = false
const DOC_CLIENT_OPERATIONS = [
'get',
'put',
'update',
'delete',
'query',
'scan'
]
function instrument(shim, AWS) {
shim.setDatastore(shim.DYNAMODB)
// DynamoDB's service API methods are dynamically generated
// in the constructor so we have to wrap the return.
shim.wrapReturn(AWS, 'DynamoDB', function wrapDynamo(shim, fn, name, ddb) {
if (dynamoProtoWrapped) {
return
}
dynamoProtoWrapped = true
shim.setDatastore(shim.DYNAMODB)
shim.recordOperation(
ddb,
OPERATIONS,
function wrapMethod(shim, original, name, args) {
DDB_OPERATIONS,
function wrapMethod(shim, original, operationName, args) {
const params = args[0]
return {
name: operationName,
parameters: {
name,
host: this.endpoint.host,
port_path_or_id: this.endpoint.port,
database_name: args[0].TableName || 'Unknown'
collection: params && params.TableName || 'Unknown'
},

@@ -43,2 +49,27 @@ callback: shim.LAST,

})
// DocumentClient's API is predefined so we can instrument the prototype.
// DocumentClient does defer to DynamoDB but it also does enough individual
// steps for the request we want to hide that instrumenting specifically and
// setting to opaque is currently required.
const docClientProto = AWS.DynamoDB.DocumentClient.prototype
shim.recordOperation(
docClientProto,
DOC_CLIENT_OPERATIONS,
function wrapOperation(shim, original, operationName, args) {
const params = args[0]
const dynamoOperation = this.serviceClientOperationsMap[operationName]
return {
name: dynamoOperation,
parameters: {
host: this.service.endpoint.host,
port_path_or_id: this.service.endpoint.port,
collection: params && params.TableName || 'Unknown'
},
callback: shim.LAST,
opaque: true
}
}
)
}

@@ -45,0 +76,0 @@

@@ -17,3 +17,3 @@ 'use strict'

function instrument(shim, AWS) {
shim.setLibrary(shim.SNS || 'SNS') // TODO: remove default after next agent release
shim.setLibrary(shim.SNS)

@@ -20,0 +20,0 @@ shim.wrapReturn(AWS, 'SNS', function wrapSns(shim, original, name, sns) {

{
"name": "@newrelic/aws-sdk",
"version": "0.2.0",
"version": "0.3.0",
"description": "New Relic instrumentation of the aws-sdk package.",

@@ -26,3 +26,3 @@ "main": "index.js",

"eslint": "^5.12.1",
"newrelic": "^5.3.0",
"newrelic": "^5.6.0",
"sinon": "^7.2.3",

@@ -29,0 +29,0 @@ "tap": "^12.4.0"

@@ -27,2 +27,3 @@ 'use strict'

}
const ITEM_DEF = {

@@ -44,2 +45,7 @@ Item: {

}
const DELETE_TABLE = {
TableName: FAKE_TABLE_NAME
}
const QUERY = {

@@ -53,13 +59,51 @@ ExpressionAttributeValues: {

const TESTS = [
{method: 'createTable', params: TABLE_DEF},
{method: 'putItem', params: ITEM_DEF},
{method: 'getItem', params: ITEM},
{method: 'updateItem', params: ITEM},
{method: 'scan', params: {TableName: TABLE_NAME}},
{method: 'query', params: QUERY},
{method: 'deleteItem', params: ITEM},
{method: 'deleteTable', params: {TableName: FAKE_TABLE_NAME}}
]
const DOC_PUT_ITEM = {
Item: {
AlbumTitle: 'Somewhat Famous',
Artist: UNIQUE_ARTIST,
SongTitle: 'Call Me Today'
},
TableName: TABLE_NAME
}
const DOC_ITEM = {
Key: {
Artist: UNIQUE_ARTIST,
SongTitle: 'Call Me Today'
},
TableName: TABLE_NAME
}
const DOC_QUERY = {
ExpressionAttributeValues: {
':v1': UNIQUE_ARTIST
},
KeyConditionExpression: 'Artist = :v1',
TableName: TABLE_NAME
}
let tests = null
function createTests(ddb, docClient) {
const composedTests = [
{api: ddb, method: 'createTable', params: TABLE_DEF, operation: 'createTable'},
{api: ddb, method: 'putItem', params: ITEM_DEF, operation: 'putItem'},
{api: ddb, method: 'getItem', params: ITEM, operation: 'getItem'},
{api: ddb, method: 'updateItem', params: ITEM, operation: 'updateItem'},
{api: ddb, method: 'scan', params: {TableName: TABLE_NAME}, operation: 'scan'},
{api: ddb, method: 'query', params: QUERY, operation: 'query'},
{api: ddb, method: 'deleteItem', params: ITEM, operation: 'deleteItem'},
{api: ddb, method: 'deleteTable', params: DELETE_TABLE, operation: 'deleteTable'},
{api: docClient, method: 'put', params: DOC_PUT_ITEM, operation: 'putItem'},
{api: docClient, method: 'get', params: DOC_ITEM, operation: 'getItem'},
{api: docClient, method: 'update', params: DOC_ITEM, operation: 'updateItem'},
{api: docClient, method: 'scan', params: {TableName: TABLE_NAME}, operation: 'scan'},
{api: docClient, method: 'query', params: DOC_QUERY, operation: 'query'},
{api: docClient, method: 'delete', params: DOC_ITEM, operation: 'deleteItem'}
]
return composedTests
}
tap.test('DynamoDB', (t) => {

@@ -70,3 +114,2 @@ t.autoend()

let AWS = null
let ddb = null

@@ -80,4 +123,9 @@ t.beforeEach((done) => {

})
AWS = require('aws-sdk')
ddb = new AWS.DynamoDB({region: 'us-east-1'})
const ddb = new AWS.DynamoDB({region: 'us-east-1'})
const docClient = new AWS.DynamoDB.DocumentClient({region: 'us-east-1'})
tests = createTests(ddb, docClient)
done()

@@ -88,2 +136,7 @@ })

helper && helper.unload()
helper = null
AWS = null
tests = null
done()

@@ -94,5 +147,5 @@ })

helper.runInTransaction((tx) => {
async.eachSeries(TESTS, (cfg, cb) => {
async.eachSeries(tests, (cfg, cb) => {
t.comment(`Testing ${cfg.method}`)
ddb[cfg.method](cfg.params, (err) => {
cfg.api[cfg.method](cfg.params, (err) => {
if (

@@ -118,5 +171,16 @@ err &&

const segments = common.checkAWSAttributes(t, tx.trace.root, /^Datastore/)
t.equal(segments.length, 8, 'should have 8 aws datastore segments')
t.equal(
segments.length,
tests.length,
`should have ${tests.length} aws datastore segments`
)
segments.forEach((segment, i) => {
const operation = tests[i].operation
t.equal(
segment.name,
`Datastore/operation/DynamoDB/${operation}`,
'should have operation in segment name'
)
const attrs = segment.attributes.get(common.SEGMENT_DESTINATION)

@@ -126,4 +190,5 @@ t.matches(attrs, {

'port_path_or_id': String,
'database_name': String,
'aws.operation': TESTS[i].method,
'product': 'DynamoDB',
'collection': String,
'aws.operation': operation,
'aws.requestId': String,

@@ -130,0 +195,0 @@ 'aws.region': 'us-east-1',

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc