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:
Bryan Kendall
2019-01-14 15:54:03 -08:00
committed by GitHub
parent 8fdca11439
commit 1e80f7ef7d
4 changed files with 63 additions and 70 deletions

View File

@@ -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

View File

@@ -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",

View File

@@ -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,
})
);
});
});

View 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 });
}
});