2018-05-22 21:43:36 +02:00
|
|
|
// Copyright 2016-2018, Pulumi Corporation.
|
|
|
|
//
|
|
|
|
// 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.
|
2017-10-08 21:10:46 +02:00
|
|
|
|
|
|
|
// The log module logs messages in a way that tightly integrates with the resource engine's interface.
|
|
|
|
|
2018-04-10 21:03:11 +02:00
|
|
|
import * as resourceTypes from "../resource";
|
2017-11-26 19:04:15 +01:00
|
|
|
import { getEngine, rpcKeepAlive } from "../runtime/settings";
|
2017-10-19 00:03:56 +02:00
|
|
|
const engproto = require("../proto/engine_pb.js");
|
2017-10-08 21:10:46 +02:00
|
|
|
|
|
|
|
let errcnt = 0;
|
|
|
|
let lastLog: Promise<any> = Promise.resolve();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* hasErrors returns true if any errors have occurred in the program.
|
|
|
|
*/
|
|
|
|
export function hasErrors(): boolean {
|
|
|
|
return errcnt > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* debug logs a debug-level message that is generally hidden from end-users.
|
|
|
|
*/
|
2020-09-24 04:06:26 +02:00
|
|
|
export function debug(msg: string, resource?: resourceTypes.Resource, streamId?: number, ephemeral?: boolean) {
|
2017-10-19 00:03:56 +02:00
|
|
|
const engine: Object | undefined = getEngine();
|
2017-10-08 21:10:46 +02:00
|
|
|
if (engine) {
|
2020-09-24 04:06:26 +02:00
|
|
|
return log(engine, engproto.LogSeverity.DEBUG, msg, resource, streamId, ephemeral);
|
2017-10-08 21:10:46 +02:00
|
|
|
}
|
|
|
|
else {
|
2020-09-24 04:06:26 +02:00
|
|
|
return Promise.resolve();
|
2017-10-08 21:10:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* info logs an informational message that is generally printed to stdout during resource operations.
|
|
|
|
*/
|
2018-10-12 20:09:09 +02:00
|
|
|
export function info(msg: string, resource?: resourceTypes.Resource, streamId?: number, ephemeral?: boolean) {
|
2017-10-19 00:03:56 +02:00
|
|
|
const engine: Object | undefined = getEngine();
|
2017-10-08 21:10:46 +02:00
|
|
|
if (engine) {
|
2018-10-12 20:09:09 +02:00
|
|
|
return log(engine, engproto.LogSeverity.INFO, msg, resource, streamId, ephemeral);
|
2017-10-08 21:10:46 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
console.log(`info: [runtime] ${msg}`);
|
2018-04-10 21:03:11 +02:00
|
|
|
return Promise.resolve();
|
2017-10-08 21:10:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* warn logs a warning to indicate that something went wrong, but not catastrophically so.
|
|
|
|
*/
|
2018-10-12 20:09:09 +02:00
|
|
|
export function warn(msg: string, resource?: resourceTypes.Resource, streamId?: number, ephemeral?: boolean) {
|
2017-10-19 00:03:56 +02:00
|
|
|
const engine: Object | undefined = getEngine();
|
2017-10-08 21:10:46 +02:00
|
|
|
if (engine) {
|
2018-10-12 20:09:09 +02:00
|
|
|
return log(engine, engproto.LogSeverity.WARNING, msg, resource, streamId, ephemeral);
|
2017-10-08 21:10:46 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
console.warn(`warning: [runtime] ${msg}`);
|
2018-04-10 21:03:11 +02:00
|
|
|
return Promise.resolve();
|
2017-10-08 21:10:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* error logs a fatal error to indicate that the tool should stop processing resource operations immediately.
|
|
|
|
*/
|
2018-10-12 20:09:09 +02:00
|
|
|
export function error(msg: string, resource?: resourceTypes.Resource, streamId?: number, ephemeral?: boolean) {
|
2017-10-08 21:10:46 +02:00
|
|
|
errcnt++; // remember the error so we can suppress leaks.
|
|
|
|
|
2017-10-19 00:03:56 +02:00
|
|
|
const engine: Object | undefined = getEngine();
|
2017-10-08 21:10:46 +02:00
|
|
|
if (engine) {
|
2018-10-12 20:09:09 +02:00
|
|
|
return log(engine, engproto.LogSeverity.ERROR, msg, resource, streamId, ephemeral);
|
2017-10-08 21:10:46 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
console.error(`error: [runtime] ${msg}`);
|
2018-04-10 21:03:11 +02:00
|
|
|
return Promise.resolve();
|
2017-10-08 21:10:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-10 21:03:11 +02:00
|
|
|
function log(
|
|
|
|
engine: any, sev: any, msg: string,
|
2018-07-12 00:04:00 +02:00
|
|
|
resource: resourceTypes.Resource | undefined,
|
2018-10-12 20:09:09 +02:00
|
|
|
streamId: number | undefined,
|
|
|
|
ephemeral: boolean | undefined): Promise<void> {
|
2018-04-10 21:03:11 +02:00
|
|
|
|
2017-10-08 21:10:46 +02:00
|
|
|
// Ensure we log everything in serial order.
|
2017-10-19 00:03:56 +02:00
|
|
|
const keepAlive: () => void = rpcKeepAlive();
|
2018-04-10 21:03:11 +02:00
|
|
|
|
|
|
|
const urnPromise = resource
|
|
|
|
? resource.urn.promise()
|
|
|
|
: Promise.resolve("");
|
|
|
|
|
2019-02-22 05:18:29 +01:00
|
|
|
lastLog = Promise.all([lastLog, urnPromise]).then(([_, urn]) => {
|
2018-04-07 17:02:59 +02:00
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
try {
|
|
|
|
const req = new engproto.LogRequest();
|
|
|
|
req.setSeverity(sev);
|
|
|
|
req.setMessage(msg);
|
2018-04-10 21:03:11 +02:00
|
|
|
req.setUrn(urn);
|
2018-07-12 00:04:00 +02:00
|
|
|
req.setStreamid(streamId === undefined ? 0 : streamId);
|
2018-10-12 20:09:09 +02:00
|
|
|
req.setEphemeral(ephemeral === true);
|
2018-04-07 17:02:59 +02:00
|
|
|
engine.log(req, () => {
|
|
|
|
resolve(); // let the next log through
|
|
|
|
keepAlive(); // permit RPC channel tear-downs
|
|
|
|
});
|
|
|
|
}
|
|
|
|
catch (err) {
|
|
|
|
reject(err);
|
|
|
|
}
|
2017-10-08 21:10:46 +02:00
|
|
|
});
|
|
|
|
});
|
2018-04-10 21:03:11 +02:00
|
|
|
|
2020-09-24 04:06:26 +02:00
|
|
|
return lastLog.catch(() => undefined);
|
2017-10-08 21:10:46 +02:00
|
|
|
}
|