UNPKG

10.2 kBJavaScriptView Raw
1"use strict";
2/*!
3 * Copyright 2015 Google Inc. All Rights Reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17Object.defineProperty(exports, "__esModule", { value: true });
18exports.Entry = exports.TRACE_SAMPLED_KEY = exports.TRACE_KEY = exports.SPAN_ID_KEY = exports.SOURCE_LOCATION_KEY = exports.OPERATION_KEY = exports.LABELS_KEY = exports.INSERT_ID_KEY = void 0;
19// eslint-disable-next-line @typescript-eslint/no-var-requires
20const EventId = require('eventid');
21const extend = require("extend");
22const common_1 = require("./utils/common");
23const http_request_1 = require("./utils/http-request");
24const context_1 = require("./utils/context");
25const eventId = new EventId();
26exports.INSERT_ID_KEY = 'logging.googleapis.com/insertId';
27exports.LABELS_KEY = 'logging.googleapis.com/labels';
28exports.OPERATION_KEY = 'logging.googleapis.com/operation';
29exports.SOURCE_LOCATION_KEY = 'logging.googleapis.com/sourceLocation';
30exports.SPAN_ID_KEY = 'logging.googleapis.com/spanId';
31exports.TRACE_KEY = 'logging.googleapis.com/trace';
32exports.TRACE_SAMPLED_KEY = 'logging.googleapis.com/trace_sampled';
33/**
34 * Create an entry object to define new data to insert into a meta.
35 *
36 * Note, {@link https://cloud.google.com/logging/quotas|Cloud Logging Quotas and limits}
37 * dictates that the maximum log entry size, including all
38 * {@link https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry|LogEntry Resource properties},
39 * cannot exceed approximately 256 KB.
40 *
41 * See {@link https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry|LogEntry JSON representation}
42 *
43 * @class
44 *
45 * @param {?object} [metadata] See a
46 * [LogEntry
47 * Resource](https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry).
48 * @param {object|string} data The data to use as the value for this log
49 * entry.
50 *
51 * If providing an object, these value types are supported:
52 * - `String`
53 * - `Number`
54 * - `Boolean`
55 * - `Buffer`
56 * - `Object`
57 * - `Array`
58 *
59 * Any other types are stringified with `String(value)`.
60 *
61 * @example
62 * ```
63 * const {Logging} = require('@google-cloud/logging');
64 * const logging = new Logging();
65 * const syslog = logging.log('syslog');
66 *
67 * const metadata = {
68 * resource: {
69 * type: 'gce_instance',
70 * labels: {
71 * zone: 'global',
72 * instance_id: '3'
73 * }
74 * }
75 * };
76 *
77 * const entry = syslog.entry(metadata, {
78 * delegate: 'my_username'
79 * });
80 *
81 * syslog.alert(entry, (err, apiResponse) => {
82 * if (!err) {
83 * // Log entry inserted successfully.
84 * }
85 * });
86 *
87 * //-
88 * // You will also receive `Entry` objects when using
89 * // Logging#getEntries() and Log#getEntries().
90 * //-
91 * logging.getEntries((err, entries) => {
92 * if (!err) {
93 * // entries[0].data = The data value from the log entry.
94 * }
95 * });
96 * ```
97 */
98class Entry {
99 constructor(metadata, data) {
100 /**
101 * @name Entry#metadata
102 * @type {object}
103 * @property {Date} timestamp
104 * @property {number} insertId
105 */
106 this.metadata = extend({
107 timestamp: new Date(),
108 }, metadata);
109 // JavaScript date has a very coarse granularity (millisecond), which makes
110 // it quite likely that multiple log entries would have the same timestamp.
111 // The Logging API doesn't guarantee to preserve insertion order for entries
112 // with the same timestamp. The service does use `insertId` as a secondary
113 // ordering for entries with the same timestamp. `insertId` needs to be
114 // globally unique (within the project) however.
115 //
116 // We use a globally unique monotonically increasing EventId as the
117 // insertId.
118 this.metadata.insertId = this.metadata.insertId || eventId.new();
119 /**
120 * @name Entry#data
121 * @type {object}
122 */
123 this.data = data;
124 }
125 /**
126 * Serialize an entry to the format the API expects. Read more:
127 * https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry
128 *
129 * @param {object} [options] Configuration object.
130 * @param {boolean} [options.removeCircular] Replace circular references in an
131 * object with a string value, `[Circular]`.
132 * @param {string} [projectId] GCP Project ID.
133 */
134 toJSON(options = {}, projectId = '') {
135 const entry = extend(true, {}, this.metadata);
136 // Format log message
137 if (Object.prototype.toString.call(this.data) === '[object Object]') {
138 entry.jsonPayload = common_1.objToStruct(this.data, {
139 removeCircular: !!options.removeCircular,
140 stringify: true,
141 });
142 }
143 else if (typeof this.data === 'string') {
144 entry.textPayload = this.data;
145 }
146 // Format log timestamp
147 if (entry.timestamp instanceof Date) {
148 const seconds = entry.timestamp.getTime() / 1000;
149 const secondsRounded = Math.floor(seconds);
150 entry.timestamp = {
151 seconds: secondsRounded,
152 nanos: Math.floor((seconds - secondsRounded) * 1e9),
153 };
154 }
155 else if (typeof entry.timestamp === 'string') {
156 entry.timestamp = common_1.zuluToDateObj(entry.timestamp);
157 }
158 // Format httpRequest
159 const req = this.metadata.httpRequest;
160 if (http_request_1.isRawHttpRequest(req)) {
161 entry.httpRequest = http_request_1.makeHttpRequestData(req);
162 // Format trace and span
163 const traceContext = this.extractTraceFromHeaders(projectId);
164 if (traceContext) {
165 if (!this.metadata.trace && traceContext.trace)
166 entry.trace = traceContext.trace;
167 if (!this.metadata.spanId && traceContext.spanId)
168 entry.spanId = traceContext.spanId;
169 if (this.metadata.traceSampled === undefined)
170 entry.traceSampled = traceContext.traceSampled;
171 }
172 }
173 return entry;
174 }
175 /**
176 * Serialize an entry to a standard format for any transports, e.g. agents.
177 * Read more: https://cloud.google.com/logging/docs/structured-logging
178 */
179 toStructuredJSON(projectId = '') {
180 const meta = this.metadata;
181 // Mask out the keys that need to be renamed.
182 /* eslint-disable @typescript-eslint/no-unused-vars */
183 const { textPayload, jsonPayload, insertId, trace, spanId, traceSampled, operation, sourceLocation, labels, ...validKeys } = meta;
184 /* eslint-enable @typescript-eslint/no-unused-vars */
185 const entry = extend(true, {}, validKeys);
186 // Re-map keys names.
187 entry[exports.LABELS_KEY] = meta.labels
188 ? Object.assign({}, meta.labels)
189 : undefined;
190 entry[exports.INSERT_ID_KEY] = meta.insertId || undefined;
191 entry[exports.TRACE_KEY] = meta.trace || undefined;
192 entry[exports.SPAN_ID_KEY] = meta.spanId || undefined;
193 entry[exports.TRACE_SAMPLED_KEY] =
194 'traceSampled' in meta && meta.traceSampled !== null
195 ? meta.traceSampled
196 : undefined;
197 // Format log payload.
198 entry.message =
199 meta.textPayload || meta.jsonPayload || meta.protoPayload || undefined;
200 entry.message = this.data || entry.message;
201 // Format timestamp
202 if (meta.timestamp instanceof Date) {
203 entry.timestamp = meta.timestamp.toISOString();
204 }
205 // Format httprequest
206 const req = meta.httpRequest;
207 if (http_request_1.isRawHttpRequest(req)) {
208 entry.httpRequest = http_request_1.makeHttpRequestData(req);
209 // Detected trace context from headers if applicable.
210 const traceContext = this.extractTraceFromHeaders(projectId);
211 if (traceContext) {
212 if (!entry[exports.TRACE_KEY] && traceContext.trace)
213 entry[exports.TRACE_KEY] = traceContext.trace;
214 if (!entry[exports.SPAN_ID_KEY] && traceContext.spanId)
215 entry[exports.SPAN_ID_KEY] = traceContext.spanId;
216 if (entry[exports.TRACE_SAMPLED_KEY] === undefined)
217 entry[exports.TRACE_SAMPLED_KEY] = traceContext.traceSampled;
218 }
219 }
220 return entry;
221 }
222 /**
223 * extractTraceFromHeaders extracts trace and span information from raw HTTP
224 * request headers only.
225 * @private
226 */
227 extractTraceFromHeaders(projectId) {
228 const rawReq = this.metadata.httpRequest;
229 if (rawReq && 'headers' in rawReq) {
230 return context_1.getOrInjectContext(rawReq, projectId, false);
231 }
232 return null;
233 }
234 /**
235 * Create an Entry object from an API response, such as `entries:list`.
236 *
237 * @private
238 *
239 * @param {object} entry An API representation of an entry. See a
240 * {@link https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry| LogEntry}.
241 * @returns {Entry}
242 */
243 static fromApiResponse_(entry) {
244 let data = entry[entry.payload];
245 if (entry.payload === 'jsonPayload') {
246 data = common_1.structToObj(data);
247 }
248 const serializedEntry = new Entry(entry, data);
249 if (entry.timestamp) {
250 let ms = Number(entry.timestamp.seconds) * 1000;
251 ms += Number(entry.timestamp.nanos) / 1e6;
252 serializedEntry.metadata.timestamp = new Date(ms);
253 }
254 return serializedEntry;
255 }
256}
257exports.Entry = Entry;
258//# sourceMappingURL=entry.js.map
\No newline at end of file