mirror of
https://github.com/zhigang1992/firebase-tools.git
synced 2026-01-12 17:22:36 +08:00
functions --open fixes, plus typescript (#1107)
* fix: functions-log use protoPayload.serviceName Possible fix for #1100 * add @types/opn * rewrite to TS, remove bad console filter logic and fix it up * add changelog entry for fixing open flag fixes #1100, #1101
This commit is contained in:
@@ -11,3 +11,4 @@ changed - Firestore emulator has various runtime improvements
|
||||
changed - Clearer empty state when pretty-printing Firestore indexes
|
||||
changed - JavasSript functions template now includes gitignore
|
||||
changed - Added node_modules/ to TypeScript functions template gitignore
|
||||
fixed - Fixed the link to the Google Cloud Console when opening Functions logs
|
||||
|
||||
@@ -111,6 +111,7 @@
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/nock": "^9.3.0",
|
||||
"@types/node": "^10.12.0",
|
||||
"@types/opn": "^5.1.0",
|
||||
"@types/request": "^2.48.1",
|
||||
"@types/sinon": "^5.0.5",
|
||||
"@types/supertest": "^2.0.6",
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var _ = require("lodash");
|
||||
|
||||
var Command = require("../command");
|
||||
var FirebaseError = require("../error");
|
||||
var gcp = require("../gcp");
|
||||
var getProjectId = require("../getProjectId");
|
||||
var logger = require("../logger");
|
||||
var requirePermissions = require("../requirePermissions");
|
||||
var open = require("opn");
|
||||
|
||||
module.exports = new Command("functions:log")
|
||||
.description("read logs from deployed functions")
|
||||
.option(
|
||||
"--only <function_names>",
|
||||
'only show logs of specified, comma-seperated functions (e.g. "funcA,funcB")'
|
||||
)
|
||||
.option("-n, --lines <num_lines>", "specify number of log lines to fetch")
|
||||
.option("--open", "open logs page in web browser")
|
||||
.before(requirePermissions, ["logging.logEntries.list", "logging.logs.list"])
|
||||
.action(function(options) {
|
||||
var projectId = getProjectId(options);
|
||||
var apiFilter = 'resource.type="cloud_function" ';
|
||||
var consoleFilter = 'metadata.serviceName:"cloudfunctions.googleapis.com"';
|
||||
if (options.only) {
|
||||
var funcNames = options.only.split(",");
|
||||
var apiFuncFilters = _.map(funcNames, function(funcName) {
|
||||
return 'resource.labels.function_name="' + funcName + '" ';
|
||||
});
|
||||
var consoleFuncFilters = _.map(funcNames, function(funcName) {
|
||||
return 'metadata.labels."cloudfunctions.googleapis.com/function_name":"' + funcName + '" ';
|
||||
});
|
||||
apiFilter += apiFuncFilters.join("OR ");
|
||||
consoleFilter = [consoleFilter, consoleFuncFilters.join("%20OR%20")].join("%0A");
|
||||
}
|
||||
if (options.open) {
|
||||
var url =
|
||||
"https://console.developers.google.com/logs/viewer?advancedFilter=" +
|
||||
consoleFilter +
|
||||
"&project=" +
|
||||
projectId;
|
||||
open(url);
|
||||
return Promise.resolve();
|
||||
}
|
||||
return gcp.cloudlogging
|
||||
.listEntries(projectId, apiFilter, options.lines || 35, "desc")
|
||||
.then(function(entries) {
|
||||
for (var i = _.size(entries); i-- > 0; ) {
|
||||
var entry = entries[i];
|
||||
logger.info(
|
||||
entry.timestamp,
|
||||
entry.severity.substring(0, 1),
|
||||
entry.resource.labels.function_name + ":",
|
||||
entry.textPayload
|
||||
);
|
||||
}
|
||||
if (_.isEmpty(entries)) {
|
||||
logger.info("No log entries found.");
|
||||
}
|
||||
return Promise.resolve(entries);
|
||||
})
|
||||
.catch(function(err) {
|
||||
return Promise.reject(
|
||||
new FirebaseError("Failed to list log entries " + err.message, {
|
||||
exit: 1,
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
61
src/commands/functions-log.ts
Normal file
61
src/commands/functions-log.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import * as _ from "lodash";
|
||||
import opn = require("opn");
|
||||
import * as qs from "querystring";
|
||||
|
||||
import * as Command from "../command";
|
||||
import * as FirebaseError from "../error";
|
||||
import * as gcp from "../gcp";
|
||||
import * as getProjectId from "../getProjectId";
|
||||
import * as logger from "../logger";
|
||||
import * as requirePermissions from "../requirePermissions";
|
||||
|
||||
module.exports = new Command("functions:log")
|
||||
.description("read logs from deployed functions")
|
||||
.option(
|
||||
"--only <function_names>",
|
||||
'only show logs of specified, comma-seperated functions (e.g. "funcA,funcB")'
|
||||
)
|
||||
.option("-n, --lines <num_lines>", "specify number of log lines to fetch")
|
||||
.option("--open", "open logs page in web browser")
|
||||
.before(requirePermissions, ["logging.logEntries.list", "logging.logs.list"])
|
||||
.action(async (options: any) => {
|
||||
try {
|
||||
const projectId = getProjectId(options, false);
|
||||
let apiFilter = `resource.type="cloud_function"`;
|
||||
if (options.only) {
|
||||
const funcNames = options.only.split(",");
|
||||
const apiFuncFilters = _.map(funcNames, (funcName) => {
|
||||
return `resource.labels.function_name="${funcName}"`;
|
||||
});
|
||||
apiFilter += `\n(${apiFuncFilters.join(" OR ")})`;
|
||||
}
|
||||
if (options.open) {
|
||||
const url = `https://console.developers.google.com/logs/viewer?advancedFilter=${qs.escape(
|
||||
apiFilter
|
||||
)}&project=${projectId}`;
|
||||
opn(url);
|
||||
return;
|
||||
}
|
||||
const entries = await gcp.cloudlogging.listEntries(
|
||||
projectId,
|
||||
apiFilter,
|
||||
options.lines || 35,
|
||||
"desc"
|
||||
);
|
||||
for (let i = _.size(entries) - 1; i >= 0; i--) {
|
||||
const entry = entries[i];
|
||||
logger.info(
|
||||
entry.timestamp,
|
||||
entry.severity.substring(0, 1),
|
||||
entry.resource.labels.function_name + ":",
|
||||
entry.textPayload
|
||||
);
|
||||
}
|
||||
if (_.isEmpty(entries)) {
|
||||
logger.info("No log entries found.");
|
||||
}
|
||||
return entries;
|
||||
} catch (err) {
|
||||
throw new FirebaseError(`Failed to list log entries ${err.message}`, { exit: 1 });
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user