Skip to content

Commit f5cfa8a

Browse files
feat: adding cloud event structured logging sample (GoogleCloudPlatform#2596)
* feat: adding cloud event structured logging sample w/ matching test refactor: fix linting errors Update index.js refactor: fix linting errors refactor: updating with suggested changes refactor: resolving sample unit test refactor: fix linting errors refactor: resolve lint errors chore: clean up refactor: adding couple more assertions & retrieving project id elsewhere chore: clean up refactor: hardcode project id chore: lint errors * refactor: denoting severity by error method, removing hardcoded projectid Co-authored-by: Averi Kitsch <akitsch@google.com>
1 parent ad28266 commit f5cfa8a

3 files changed

Lines changed: 132 additions & 0 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
// [START functions_structured_logging_event]
18+
const {Logging} = require('@google-cloud/logging');
19+
const functions = require('@google-cloud/functions-framework');
20+
const pkg = require('./package.json');
21+
22+
functions.cloudEvent('structuredLoggingEvent', async () => {
23+
// Initialize the logging client
24+
const logging = new Logging();
25+
// Create a LogSync transport, defaulting to process.stdout
26+
const log = logging.logSync(pkg.name);
27+
// Required to capture your project id
28+
await logging.setProjectId();
29+
const text = 'Hello, world!';
30+
const entry = log.entry(
31+
{
32+
component: 'arbitrary-property',
33+
},
34+
text
35+
);
36+
// Indicates severity using error()
37+
log.error(entry);
38+
});
39+
// [END functions_structured_logging_event]
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "structured-logging-cloudevent",
3+
"version": "0.0.1",
4+
"description": "Simple structured logging clouevent example",
5+
"license": "Apache-2.0",
6+
"author": "Google LLC",
7+
"main": "index.js",
8+
"engines": {
9+
"node": ">=12.0.0"
10+
},
11+
"scripts": {
12+
"test": "mocha test/*.test.js"
13+
},
14+
"dependencies": {
15+
"@google-cloud/functions-framework": "^3.1.0",
16+
"@google-cloud/logging": "^9.8.0"
17+
},
18+
"devDependencies": {
19+
"assert": "^2.0.0",
20+
"cloudevents": "^6.0.1",
21+
"mocha": "^9.2.2",
22+
"sinon": "^13.0.1"
23+
}
24+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
const assert = require('assert');
18+
const sinon = require('sinon');
19+
const {getFunction} = require('@google-cloud/functions-framework/testing');
20+
const {Logging} = require('@google-cloud/logging');
21+
const {CloudEvent} = require('cloudevents');
22+
const pkg = require('../package.json');
23+
// Importing our target file
24+
require('../index.js');
25+
26+
describe('structured logging: functions cloudevent', () => {
27+
let projectId;
28+
29+
before(async () => {
30+
const logging = new Logging();
31+
projectId = await logging.auth.getProjectId();
32+
// Adding a spy to the write function in stdout
33+
sinon.spy(process.stdout, 'write');
34+
});
35+
36+
afterEach(() => {
37+
process.stdout.write.restore();
38+
});
39+
40+
it('structuredLoggingEvent: should correctly print logs', async () => {
41+
const structuredLoggingEvent = getFunction('structuredLoggingEvent');
42+
43+
const expected = {
44+
severity: 'NOTICE',
45+
component: 'arbitrary-property',
46+
logName: `projects/${projectId}/logs/${pkg.name}`,
47+
message: 'Hello, world!',
48+
};
49+
50+
// Passing in a mocked CloudEvent object
51+
await structuredLoggingEvent(
52+
new CloudEvent({
53+
type: 'google.cloud.pubsub.topic.v2.messagePublished',
54+
source: '//pubsub.googleapis.com/test-topic',
55+
})
56+
);
57+
58+
assert.ok(process.stdout.write.calledOnce);
59+
assert.ok(process.stdout.write.getCall(0).args.length);
60+
61+
// Capture the string output & parse
62+
const result = JSON.parse(process.stdout.write.getCall(0).args[0]);
63+
64+
assert.equal(result.severity, expected.severity);
65+
assert.equal(result.logName, expected.logName);
66+
assert.equal(result.component, expected.component);
67+
assert.equal(result.message, expected.message);
68+
});
69+
});

0 commit comments

Comments
 (0)