log.js

"use strict";
/*!
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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.
 */
Object.defineProperty(exports, "__esModule", { value: true });
const promisify_1 = require("@google-cloud/promisify");
const arrify = require("arrify");
const extend = require("extend");
const entry_1 = require("./entry");
const metadata_1 = require("./metadata");
const snakeCaseKeys = require('snakecase-keys');
var Severity;
(function (Severity) {
    Severity[Severity["emergency"] = 0] = "emergency";
    Severity[Severity["alert"] = 1] = "alert";
    Severity[Severity["critical"] = 2] = "critical";
    Severity[Severity["error"] = 3] = "error";
    Severity[Severity["warning"] = 4] = "warning";
    Severity[Severity["notice"] = 5] = "notice";
    Severity[Severity["info"] = 6] = "info";
    Severity[Severity["debug"] = 7] = "debug";
})(Severity = exports.Severity || (exports.Severity = {}));
/**
 * A log is a named collection of entries, each entry representing a timestamped
 * event. Logs can be produced by Google Cloud Platform services, by third-party
 * services, or by your applications. For example, the log `apache-access` is
 * produced by the Apache Web Server, but the log
 * `compute.googleapis.com/activity_log` is produced by Google Compute Engine.
 *
 * @see [Introduction to Logs]{@link https://cloud.google.com/logging/docs/basic-concepts#logs}
 *
 * @class
 *
 * @param {Logging} logging {@link Logging} instance.
 * @param {string} name Name of the log.
 * @param {object} [options] Configuration object.
 * @param {boolean} [options.removeCircular] Replace circular references in
 *     logged objects with a string value, `[Circular]`. (Default: false)
 *
 * @example
 * const {Logging} = require('@google-cloud/logging');
 * const logging = new Logging();
 * const log = logging.log('syslog');
 */
class Log {
    constructor(logging, name, options) {
        options = options || {};
        this.formattedName_ = Log.formatName_(logging.projectId, name);
        this.removeCircular_ = options.removeCircular === true;
        this.logging = logging;
        /**
         * @name Log#name
         * @type {string}
         */
        this.name = this.formattedName_.split('/').pop();
    }
    alert(entry, options) {
        return this.write(Log.assignSeverityToEntries_(entry, 'ALERT'), options);
    }
    critical(entry, options) {
        return this.write(Log.assignSeverityToEntries_(entry, 'CRITICAL'), options);
    }
    debug(entry, options) {
        return this.write(Log.assignSeverityToEntries_(entry, 'DEBUG'), options);
    }
    async delete(gaxOptions) {
        const projectId = await this.logging.auth.getProjectId();
        this.formattedName_ = Log.formatName_(projectId, this.name);
        const reqOpts = {
            logName: this.formattedName_,
        };
        return this.logging.loggingService.deleteLog(reqOpts, gaxOptions);
    }
    emergency(entry, options) {
        return this.write(Log.assignSeverityToEntries_(entry, 'EMERGENCY'), options);
    }
    entry(metadataOrData, data) {
        let metadata;
        if (!data) {
            data = metadataOrData;
            metadata = {};
        }
        else {
            metadata = metadataOrData;
        }
        return this.logging.entry(metadata, data);
    }
    error(entry, options) {
        return this.write(Log.assignSeverityToEntries_(entry, 'ERROR'), options);
    }
    async getEntries(opts) {
        const options = extend({}, opts);
        const projectId = await this.logging.auth.getProjectId();
        this.formattedName_ = Log.formatName_(projectId, this.name);
        if (options.filter) {
            options.filter = `(${options.filter}) AND logName="${this.formattedName_}"`;
        }
        else {
            options.filter = `logName="${this.formattedName_}"`;
        }
        return this.logging.getEntries(options);
    }
    /**
     * This method is a wrapper around {module:logging#getEntriesStream}, but with
     * a filter specified to only return {module:logging/entry} objects from this
     * log.
     *
     * @method Log#getEntriesStream
     * @param {GetEntriesRequest} [query] Query object for listing entries.
     * @returns {ReadableStream} A readable stream that emits {@link Entry}
     *     instances.
     *
     * @example
     * const {Logging} = require('@google-cloud/logging');
     * const logging = new Logging();
     * const log = logging.log('my-log');
     *
     * log.getEntriesStream()
     *   .on('error', console.error)
     *   .on('data', entry => {
     *     // `entry` is a Stackdriver Logging entry object.
     *     // See the `data` property to read the data from the entry.
     *   })
     *   .on('end', function() {
     *     // All entries retrieved.
     *   });
     *
     * //-
     * // If you anticipate many results, you can end a stream early to prevent
     * // unnecessary processing and API requests.
     * //-
     * log.getEntriesStream()
     *   .on('data', function(entry) {
     *     this.end();
     *   });
     */
    getEntriesStream(options) {
        options = extend({
            log: this.name,
        }, options);
        return this.logging.getEntriesStream(options);
    }
    info(entry, options) {
        return this.write(Log.assignSeverityToEntries_(entry, 'INFO'), options);
    }
    notice(entry, options) {
        return this.write(Log.assignSeverityToEntries_(entry, 'NOTICE'), options);
    }
    warning(entry, options) {
        return this.write(Log.assignSeverityToEntries_(entry, 'WARNING'), options);
    }
    async write(entry, opts) {
        const options = opts ? opts : {};
        const self = this;
        if (options.resource) {
            if (options.resource.labels) {
                options.resource.labels = snakeCaseKeys(options.resource.labels);
            }
            return writeWithResource(options.resource);
        }
        else if (this.logging.detectedResource) {
            return writeWithResource(this.logging.detectedResource);
        }
        else {
            const resource = await metadata_1.getDefaultResource(this.logging.auth);
            this.logging.detectedResource = resource;
            return writeWithResource(resource);
        }
        async function writeWithResource(resource) {
            let decoratedEntries;
            try {
                decoratedEntries = self.decorateEntries_(arrify(entry));
            }
            catch (err) {
                // Ignore errors (the API will speak up if it has an issue).
            }
            const projectId = await self.logging.auth.getProjectId();
            self.formattedName_ = Log.formatName_(projectId, self.name);
            const reqOpts = extend({
                logName: self.formattedName_,
                entries: decoratedEntries,
                resource,
            }, options);
            delete reqOpts.gaxOptions;
            return self.logging.loggingService.writeLogEntries(reqOpts, options.gaxOptions);
        }
    }
    /**
     * All entries are passed through here in order to get them serialized.
     *
     * @private
     *
     * @param {object[]} entries - Entry objects.
     * @returns {object[]} Serialized entries.
     * @throws if there is an error during serialization.
     */
    decorateEntries_(entries) {
        return entries.map(entry => {
            if (!(entry instanceof entry_1.Entry)) {
                entry = this.entry(entry);
            }
            return entry.toJSON({
                removeCircular: this.removeCircular_,
            });
        });
    }
    /**
     * Return an array of log entries with the desired severity assigned.
     *
     * @private
     *
     * @param {object|object[]} entries - Log entries.
     * @param {string} severity - The desired severity level.
     */
    static assignSeverityToEntries_(entries, severity) {
        return arrify(entries).map(entry => {
            const metadata = extend(true, {}, entry.metadata, {
                severity,
            });
            return extend(new entry_1.Entry(), entry, {
                metadata,
            });
        });
    }
    /**
     * Format the name of a log. A log's full name is in the format of
     * 'projects/{projectId}/logs/{logName}'.
     *
     * @private
     *
     * @returns {string}
     */
    static formatName_(projectId, name) {
        const path = 'projects/' + projectId + '/logs/';
        name = name.replace(path, '');
        if (decodeURIComponent(name) === name) {
            // The name has not been encoded yet.
            name = encodeURIComponent(name);
        }
        return path + name;
    }
}
exports.Log = Log;
/*! Developer Documentation
 *
 * All async methods (except for streams) will call a callback in the event
 * that a callback is provided .
 */
promisify_1.callbackifyAll(Log, { exclude: ['entry', 'getEntriesStream'] });
//# sourceMappingURL=log.js.map