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.
|
2016-11-15 20:30:34 +01:00
|
|
|
|
|
|
|
package diag
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
2016-11-17 02:52:14 +01:00
|
|
|
"io"
|
2017-07-14 02:09:46 +02:00
|
|
|
"io/ioutil"
|
2016-11-16 01:30:10 +01:00
|
|
|
|
2017-09-22 04:18:21 +02:00
|
|
|
"github.com/pulumi/pulumi/pkg/diag/colors"
|
|
|
|
"github.com/pulumi/pulumi/pkg/util/contract"
|
2018-05-16 00:28:00 +02:00
|
|
|
"github.com/pulumi/pulumi/pkg/util/logging"
|
2016-11-15 20:30:34 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// Sink facilitates pluggable diagnostics messages.
|
|
|
|
type Sink interface {
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
// Logf issues a log message.
|
|
|
|
Logf(sev Severity, diag *Diag, args ...interface{})
|
|
|
|
// Debugf issues a debugging message.
|
|
|
|
Debugf(diag *Diag, args ...interface{})
|
Improve output formatting
This change improves our output formatting by generally adding
fewer prefixes. As shown in pulumi/pulumi#359, we were being
excessively verbose in many places, including prefixing every
console.out with "langhost[nodejs].stdout: ", displaying full
stack traces for simple errors like missing configuration, etc.
Overall, this change includes the following:
* Don't prefix stdout and stderr output from the program, other
than the standard "info:" prefix. I experimented with various
schemes here, but they all felt gratuitous. Simply emitting
the output seems fine, especially as it's closer to what would
happen if you just ran the program under node.
* Do NOT make writes to stderr fail the plan/deploy. Previously
we assumed that any console.errors, for instance, meant that
the overall program should fail. This simply isn't how stderr
is treated generally and meant you couldn't use certain
logging techniques and libraries, among other things.
* Do make sure that stderr writes in the program end up going to
stderr in the Pulumi CLI output, however, so that redirection
works as it should. This required a new Infoerr log level.
* Make a small fix to the planning logic so we don't attempt to
print the summary if an error occurs.
* Finally, add a new error type, RunError, that when thrown and
uncaught does not result in a full stack trace being printed.
Anyone can use this, however, we currently use it for config
errors so that we can terminate with a pretty error message,
rather than the monstrosity shown in pulumi/pulumi#359.
2017-09-23 14:20:11 +02:00
|
|
|
// Infof issues an informational message (to stdout).
|
2017-02-23 03:53:36 +01:00
|
|
|
Infof(diag *Diag, args ...interface{})
|
Improve output formatting
This change improves our output formatting by generally adding
fewer prefixes. As shown in pulumi/pulumi#359, we were being
excessively verbose in many places, including prefixing every
console.out with "langhost[nodejs].stdout: ", displaying full
stack traces for simple errors like missing configuration, etc.
Overall, this change includes the following:
* Don't prefix stdout and stderr output from the program, other
than the standard "info:" prefix. I experimented with various
schemes here, but they all felt gratuitous. Simply emitting
the output seems fine, especially as it's closer to what would
happen if you just ran the program under node.
* Do NOT make writes to stderr fail the plan/deploy. Previously
we assumed that any console.errors, for instance, meant that
the overall program should fail. This simply isn't how stderr
is treated generally and meant you couldn't use certain
logging techniques and libraries, among other things.
* Do make sure that stderr writes in the program end up going to
stderr in the Pulumi CLI output, however, so that redirection
works as it should. This required a new Infoerr log level.
* Make a small fix to the planning logic so we don't attempt to
print the summary if an error occurs.
* Finally, add a new error type, RunError, that when thrown and
uncaught does not result in a full stack trace being printed.
Anyone can use this, however, we currently use it for config
errors so that we can terminate with a pretty error message,
rather than the monstrosity shown in pulumi/pulumi#359.
2017-09-23 14:20:11 +02:00
|
|
|
// Infoerrf issues an informational message (to stderr).
|
|
|
|
Infoerrf(diag *Diag, args ...interface{})
|
2017-02-23 03:53:36 +01:00
|
|
|
// Errorf issues a new error diagnostic.
|
2016-11-15 20:30:34 +01:00
|
|
|
Errorf(diag *Diag, args ...interface{})
|
2017-02-23 03:53:36 +01:00
|
|
|
// Warningf issues a new warning diagnostic.
|
2016-11-15 20:30:34 +01:00
|
|
|
Warningf(diag *Diag, args ...interface{})
|
2016-11-16 04:16:02 +01:00
|
|
|
|
2018-05-08 00:11:52 +02:00
|
|
|
// Stringify stringifies a diagnostic into a prefix and message that is appropriate for printing.
|
|
|
|
Stringify(sev Severity, diag *Diag, args ...interface{}) (string, string)
|
2017-02-10 02:26:49 +01:00
|
|
|
}
|
|
|
|
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
// Severity dictates the kind of diagnostic.
|
|
|
|
type Severity string
|
2017-02-10 02:26:49 +01:00
|
|
|
|
|
|
|
const (
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
Debug Severity = "debug"
|
|
|
|
Info Severity = "info"
|
Improve output formatting
This change improves our output formatting by generally adding
fewer prefixes. As shown in pulumi/pulumi#359, we were being
excessively verbose in many places, including prefixing every
console.out with "langhost[nodejs].stdout: ", displaying full
stack traces for simple errors like missing configuration, etc.
Overall, this change includes the following:
* Don't prefix stdout and stderr output from the program, other
than the standard "info:" prefix. I experimented with various
schemes here, but they all felt gratuitous. Simply emitting
the output seems fine, especially as it's closer to what would
happen if you just ran the program under node.
* Do NOT make writes to stderr fail the plan/deploy. Previously
we assumed that any console.errors, for instance, meant that
the overall program should fail. This simply isn't how stderr
is treated generally and meant you couldn't use certain
logging techniques and libraries, among other things.
* Do make sure that stderr writes in the program end up going to
stderr in the Pulumi CLI output, however, so that redirection
works as it should. This required a new Infoerr log level.
* Make a small fix to the planning logic so we don't attempt to
print the summary if an error occurs.
* Finally, add a new error type, RunError, that when thrown and
uncaught does not result in a full stack trace being printed.
Anyone can use this, however, we currently use it for config
errors so that we can terminate with a pretty error message,
rather than the monstrosity shown in pulumi/pulumi#359.
2017-09-23 14:20:11 +02:00
|
|
|
Infoerr Severity = "info#err"
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
Warning Severity = "warning"
|
|
|
|
Error Severity = "error"
|
2017-02-10 02:26:49 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// FormatOptions controls the output style and content.
|
|
|
|
type FormatOptions struct {
|
2017-12-18 20:42:32 +01:00
|
|
|
Pwd string // the working directory.
|
|
|
|
Color colors.Colorization // how output should be colorized.
|
|
|
|
Debug bool // if true, debugging will be output to stdout.
|
2016-11-15 20:30:34 +01:00
|
|
|
}
|
|
|
|
|
2017-01-28 00:42:39 +01:00
|
|
|
// DefaultSink returns a default sink that simply logs output to stderr/stdout.
|
2017-10-05 23:08:46 +02:00
|
|
|
func DefaultSink(stdout io.Writer, stderr io.Writer, opts FormatOptions) Sink {
|
|
|
|
contract.Require(stdout != nil, "stdout")
|
|
|
|
contract.Require(stderr != nil, "stderr")
|
Improve output formatting
This change improves our output formatting by generally adding
fewer prefixes. As shown in pulumi/pulumi#359, we were being
excessively verbose in many places, including prefixing every
console.out with "langhost[nodejs].stdout: ", displaying full
stack traces for simple errors like missing configuration, etc.
Overall, this change includes the following:
* Don't prefix stdout and stderr output from the program, other
than the standard "info:" prefix. I experimented with various
schemes here, but they all felt gratuitous. Simply emitting
the output seems fine, especially as it's closer to what would
happen if you just ran the program under node.
* Do NOT make writes to stderr fail the plan/deploy. Previously
we assumed that any console.errors, for instance, meant that
the overall program should fail. This simply isn't how stderr
is treated generally and meant you couldn't use certain
logging techniques and libraries, among other things.
* Do make sure that stderr writes in the program end up going to
stderr in the Pulumi CLI output, however, so that redirection
works as it should. This required a new Infoerr log level.
* Make a small fix to the planning logic so we don't attempt to
print the summary if an error occurs.
* Finally, add a new error type, RunError, that when thrown and
uncaught does not result in a full stack trace being printed.
Anyone can use this, however, we currently use it for config
errors so that we can terminate with a pretty error message,
rather than the monstrosity shown in pulumi/pulumi#359.
2017-09-23 14:20:11 +02:00
|
|
|
// Discard debug output by default unless requested.
|
|
|
|
debug := ioutil.Discard
|
2017-07-14 02:09:46 +02:00
|
|
|
if opts.Debug {
|
2017-08-23 02:46:06 +02:00
|
|
|
debug = stdout
|
2017-07-14 02:09:46 +02:00
|
|
|
}
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
return newDefaultSink(opts, map[Severity]io.Writer{
|
2017-07-14 02:09:46 +02:00
|
|
|
Debug: debug,
|
2017-08-23 02:46:06 +02:00
|
|
|
Info: stdout,
|
Improve output formatting
This change improves our output formatting by generally adding
fewer prefixes. As shown in pulumi/pulumi#359, we were being
excessively verbose in many places, including prefixing every
console.out with "langhost[nodejs].stdout: ", displaying full
stack traces for simple errors like missing configuration, etc.
Overall, this change includes the following:
* Don't prefix stdout and stderr output from the program, other
than the standard "info:" prefix. I experimented with various
schemes here, but they all felt gratuitous. Simply emitting
the output seems fine, especially as it's closer to what would
happen if you just ran the program under node.
* Do NOT make writes to stderr fail the plan/deploy. Previously
we assumed that any console.errors, for instance, meant that
the overall program should fail. This simply isn't how stderr
is treated generally and meant you couldn't use certain
logging techniques and libraries, among other things.
* Do make sure that stderr writes in the program end up going to
stderr in the Pulumi CLI output, however, so that redirection
works as it should. This required a new Infoerr log level.
* Make a small fix to the planning logic so we don't attempt to
print the summary if an error occurs.
* Finally, add a new error type, RunError, that when thrown and
uncaught does not result in a full stack trace being printed.
Anyone can use this, however, we currently use it for config
errors so that we can terminate with a pretty error message,
rather than the monstrosity shown in pulumi/pulumi#359.
2017-09-23 14:20:11 +02:00
|
|
|
Infoerr: stderr,
|
2017-08-23 02:46:06 +02:00
|
|
|
Error: stderr,
|
|
|
|
Warning: stderr,
|
2017-02-23 03:53:36 +01:00
|
|
|
})
|
2016-11-17 02:52:14 +01:00
|
|
|
}
|
|
|
|
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
func newDefaultSink(opts FormatOptions, writers map[Severity]io.Writer) *defaultSink {
|
2017-07-14 02:09:46 +02:00
|
|
|
contract.Assert(writers[Debug] != nil)
|
2017-02-23 03:53:36 +01:00
|
|
|
contract.Assert(writers[Info] != nil)
|
Improve output formatting
This change improves our output formatting by generally adding
fewer prefixes. As shown in pulumi/pulumi#359, we were being
excessively verbose in many places, including prefixing every
console.out with "langhost[nodejs].stdout: ", displaying full
stack traces for simple errors like missing configuration, etc.
Overall, this change includes the following:
* Don't prefix stdout and stderr output from the program, other
than the standard "info:" prefix. I experimented with various
schemes here, but they all felt gratuitous. Simply emitting
the output seems fine, especially as it's closer to what would
happen if you just ran the program under node.
* Do NOT make writes to stderr fail the plan/deploy. Previously
we assumed that any console.errors, for instance, meant that
the overall program should fail. This simply isn't how stderr
is treated generally and meant you couldn't use certain
logging techniques and libraries, among other things.
* Do make sure that stderr writes in the program end up going to
stderr in the Pulumi CLI output, however, so that redirection
works as it should. This required a new Infoerr log level.
* Make a small fix to the planning logic so we don't attempt to
print the summary if an error occurs.
* Finally, add a new error type, RunError, that when thrown and
uncaught does not result in a full stack trace being printed.
Anyone can use this, however, we currently use it for config
errors so that we can terminate with a pretty error message,
rather than the monstrosity shown in pulumi/pulumi#359.
2017-09-23 14:20:11 +02:00
|
|
|
contract.Assert(writers[Infoerr] != nil)
|
2017-02-23 03:53:36 +01:00
|
|
|
contract.Assert(writers[Error] != nil)
|
|
|
|
contract.Assert(writers[Warning] != nil)
|
|
|
|
return &defaultSink{
|
|
|
|
opts: opts,
|
|
|
|
writers: writers,
|
|
|
|
}
|
2016-11-15 20:30:34 +01:00
|
|
|
}
|
|
|
|
|
Improve output formatting
This change improves our output formatting by generally adding
fewer prefixes. As shown in pulumi/pulumi#359, we were being
excessively verbose in many places, including prefixing every
console.out with "langhost[nodejs].stdout: ", displaying full
stack traces for simple errors like missing configuration, etc.
Overall, this change includes the following:
* Don't prefix stdout and stderr output from the program, other
than the standard "info:" prefix. I experimented with various
schemes here, but they all felt gratuitous. Simply emitting
the output seems fine, especially as it's closer to what would
happen if you just ran the program under node.
* Do NOT make writes to stderr fail the plan/deploy. Previously
we assumed that any console.errors, for instance, meant that
the overall program should fail. This simply isn't how stderr
is treated generally and meant you couldn't use certain
logging techniques and libraries, among other things.
* Do make sure that stderr writes in the program end up going to
stderr in the Pulumi CLI output, however, so that redirection
works as it should. This required a new Infoerr log level.
* Make a small fix to the planning logic so we don't attempt to
print the summary if an error occurs.
* Finally, add a new error type, RunError, that when thrown and
uncaught does not result in a full stack trace being printed.
Anyone can use this, however, we currently use it for config
errors so that we can terminate with a pretty error message,
rather than the monstrosity shown in pulumi/pulumi#359.
2017-09-23 14:20:11 +02:00
|
|
|
const DefaultSinkIDPrefix = "PU"
|
2016-11-16 17:19:26 +01:00
|
|
|
|
2016-11-16 01:30:10 +01:00
|
|
|
// defaultSink is the default sink which logs output to stderr/stdout.
|
|
|
|
type defaultSink struct {
|
2017-02-23 03:53:36 +01:00
|
|
|
opts FormatOptions // a set of options that control output style and content.
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
writers map[Severity]io.Writer // the writers to use for each kind of diagnostic severity.
|
2016-11-15 20:30:34 +01:00
|
|
|
}
|
|
|
|
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
func (d *defaultSink) Logf(sev Severity, diag *Diag, args ...interface{}) {
|
|
|
|
switch sev {
|
|
|
|
case Debug:
|
|
|
|
d.Debugf(diag, args...)
|
|
|
|
case Info:
|
|
|
|
d.Infof(diag, args...)
|
Improve output formatting
This change improves our output formatting by generally adding
fewer prefixes. As shown in pulumi/pulumi#359, we were being
excessively verbose in many places, including prefixing every
console.out with "langhost[nodejs].stdout: ", displaying full
stack traces for simple errors like missing configuration, etc.
Overall, this change includes the following:
* Don't prefix stdout and stderr output from the program, other
than the standard "info:" prefix. I experimented with various
schemes here, but they all felt gratuitous. Simply emitting
the output seems fine, especially as it's closer to what would
happen if you just ran the program under node.
* Do NOT make writes to stderr fail the plan/deploy. Previously
we assumed that any console.errors, for instance, meant that
the overall program should fail. This simply isn't how stderr
is treated generally and meant you couldn't use certain
logging techniques and libraries, among other things.
* Do make sure that stderr writes in the program end up going to
stderr in the Pulumi CLI output, however, so that redirection
works as it should. This required a new Infoerr log level.
* Make a small fix to the planning logic so we don't attempt to
print the summary if an error occurs.
* Finally, add a new error type, RunError, that when thrown and
uncaught does not result in a full stack trace being printed.
Anyone can use this, however, we currently use it for config
errors so that we can terminate with a pretty error message,
rather than the monstrosity shown in pulumi/pulumi#359.
2017-09-23 14:20:11 +02:00
|
|
|
case Infoerr:
|
|
|
|
d.Infoerrf(diag, args...)
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
case Warning:
|
|
|
|
d.Warningf(diag, args...)
|
|
|
|
case Error:
|
|
|
|
d.Errorf(diag, args...)
|
|
|
|
default:
|
|
|
|
contract.Failf("Unrecognized severity: %v", sev)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-08 00:11:52 +02:00
|
|
|
func (d *defaultSink) createMessage(sev Severity, diag *Diag, args ...interface{}) string {
|
|
|
|
prefix, msg := d.Stringify(sev, diag, args...)
|
|
|
|
return prefix + msg
|
|
|
|
}
|
|
|
|
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
func (d *defaultSink) Debugf(diag *Diag, args ...interface{}) {
|
2017-07-14 02:09:46 +02:00
|
|
|
// For debug messages, write both to the glogger and a stream, if there is one.
|
2018-05-16 00:28:00 +02:00
|
|
|
logging.V(3).Infof(diag.Message, args...)
|
2018-05-08 00:11:52 +02:00
|
|
|
msg := d.createMessage(Debug, diag, args...)
|
2018-05-16 00:28:00 +02:00
|
|
|
if logging.V(9) {
|
|
|
|
logging.V(9).Infof("defaultSink::Debug(%v)", msg[:len(msg)-1])
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
}
|
2017-10-26 19:30:30 +02:00
|
|
|
fmt.Fprint(d.writers[Debug], msg)
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
}
|
|
|
|
|
2017-02-23 03:53:36 +01:00
|
|
|
func (d *defaultSink) Infof(diag *Diag, args ...interface{}) {
|
2018-05-08 00:11:52 +02:00
|
|
|
msg := d.createMessage(Info, diag, args...)
|
2018-05-16 00:28:00 +02:00
|
|
|
if logging.V(5) {
|
|
|
|
logging.V(5).Infof("defaultSink::Info(%v)", msg[:len(msg)-1])
|
2017-02-23 03:53:36 +01:00
|
|
|
}
|
2017-10-26 19:30:30 +02:00
|
|
|
fmt.Fprint(d.writers[Info], msg)
|
2016-11-22 18:40:09 +01:00
|
|
|
}
|
|
|
|
|
Improve output formatting
This change improves our output formatting by generally adding
fewer prefixes. As shown in pulumi/pulumi#359, we were being
excessively verbose in many places, including prefixing every
console.out with "langhost[nodejs].stdout: ", displaying full
stack traces for simple errors like missing configuration, etc.
Overall, this change includes the following:
* Don't prefix stdout and stderr output from the program, other
than the standard "info:" prefix. I experimented with various
schemes here, but they all felt gratuitous. Simply emitting
the output seems fine, especially as it's closer to what would
happen if you just ran the program under node.
* Do NOT make writes to stderr fail the plan/deploy. Previously
we assumed that any console.errors, for instance, meant that
the overall program should fail. This simply isn't how stderr
is treated generally and meant you couldn't use certain
logging techniques and libraries, among other things.
* Do make sure that stderr writes in the program end up going to
stderr in the Pulumi CLI output, however, so that redirection
works as it should. This required a new Infoerr log level.
* Make a small fix to the planning logic so we don't attempt to
print the summary if an error occurs.
* Finally, add a new error type, RunError, that when thrown and
uncaught does not result in a full stack trace being printed.
Anyone can use this, however, we currently use it for config
errors so that we can terminate with a pretty error message,
rather than the monstrosity shown in pulumi/pulumi#359.
2017-09-23 14:20:11 +02:00
|
|
|
func (d *defaultSink) Infoerrf(diag *Diag, args ...interface{}) {
|
2018-05-08 00:11:52 +02:00
|
|
|
msg := d.createMessage(Info /* not Infoerr, just "info: "*/, diag, args...)
|
2018-05-16 00:28:00 +02:00
|
|
|
if logging.V(5) {
|
|
|
|
logging.V(5).Infof("defaultSink::Infoerr(%v)", msg[:len(msg)-1])
|
Improve output formatting
This change improves our output formatting by generally adding
fewer prefixes. As shown in pulumi/pulumi#359, we were being
excessively verbose in many places, including prefixing every
console.out with "langhost[nodejs].stdout: ", displaying full
stack traces for simple errors like missing configuration, etc.
Overall, this change includes the following:
* Don't prefix stdout and stderr output from the program, other
than the standard "info:" prefix. I experimented with various
schemes here, but they all felt gratuitous. Simply emitting
the output seems fine, especially as it's closer to what would
happen if you just ran the program under node.
* Do NOT make writes to stderr fail the plan/deploy. Previously
we assumed that any console.errors, for instance, meant that
the overall program should fail. This simply isn't how stderr
is treated generally and meant you couldn't use certain
logging techniques and libraries, among other things.
* Do make sure that stderr writes in the program end up going to
stderr in the Pulumi CLI output, however, so that redirection
works as it should. This required a new Infoerr log level.
* Make a small fix to the planning logic so we don't attempt to
print the summary if an error occurs.
* Finally, add a new error type, RunError, that when thrown and
uncaught does not result in a full stack trace being printed.
Anyone can use this, however, we currently use it for config
errors so that we can terminate with a pretty error message,
rather than the monstrosity shown in pulumi/pulumi#359.
2017-09-23 14:20:11 +02:00
|
|
|
}
|
2017-10-26 19:30:30 +02:00
|
|
|
fmt.Fprint(d.writers[Infoerr], msg)
|
Improve output formatting
This change improves our output formatting by generally adding
fewer prefixes. As shown in pulumi/pulumi#359, we were being
excessively verbose in many places, including prefixing every
console.out with "langhost[nodejs].stdout: ", displaying full
stack traces for simple errors like missing configuration, etc.
Overall, this change includes the following:
* Don't prefix stdout and stderr output from the program, other
than the standard "info:" prefix. I experimented with various
schemes here, but they all felt gratuitous. Simply emitting
the output seems fine, especially as it's closer to what would
happen if you just ran the program under node.
* Do NOT make writes to stderr fail the plan/deploy. Previously
we assumed that any console.errors, for instance, meant that
the overall program should fail. This simply isn't how stderr
is treated generally and meant you couldn't use certain
logging techniques and libraries, among other things.
* Do make sure that stderr writes in the program end up going to
stderr in the Pulumi CLI output, however, so that redirection
works as it should. This required a new Infoerr log level.
* Make a small fix to the planning logic so we don't attempt to
print the summary if an error occurs.
* Finally, add a new error type, RunError, that when thrown and
uncaught does not result in a full stack trace being printed.
Anyone can use this, however, we currently use it for config
errors so that we can terminate with a pretty error message,
rather than the monstrosity shown in pulumi/pulumi#359.
2017-09-23 14:20:11 +02:00
|
|
|
}
|
|
|
|
|
2016-11-16 01:30:10 +01:00
|
|
|
func (d *defaultSink) Errorf(diag *Diag, args ...interface{}) {
|
2018-05-08 00:11:52 +02:00
|
|
|
msg := d.createMessage(Error, diag, args...)
|
2018-05-16 00:28:00 +02:00
|
|
|
if logging.V(5) {
|
|
|
|
logging.V(5).Infof("defaultSink::Error(%v)", msg[:len(msg)-1])
|
2016-11-16 01:30:10 +01:00
|
|
|
}
|
2017-10-26 19:30:30 +02:00
|
|
|
fmt.Fprint(d.writers[Error], msg)
|
2016-11-15 20:30:34 +01:00
|
|
|
}
|
|
|
|
|
2016-11-16 01:30:10 +01:00
|
|
|
func (d *defaultSink) Warningf(diag *Diag, args ...interface{}) {
|
2018-05-08 00:11:52 +02:00
|
|
|
msg := d.createMessage(Warning, diag, args...)
|
2018-05-16 00:28:00 +02:00
|
|
|
if logging.V(5) {
|
|
|
|
logging.V(5).Infof("defaultSink::Warning(%v)", msg[:len(msg)-1])
|
2016-11-16 01:30:10 +01:00
|
|
|
}
|
2017-10-26 19:30:30 +02:00
|
|
|
fmt.Fprint(d.writers[Warning], msg)
|
2016-11-15 20:30:34 +01:00
|
|
|
}
|
|
|
|
|
2018-05-08 00:11:52 +02:00
|
|
|
func (d *defaultSink) Stringify(sev Severity, diag *Diag, args ...interface{}) (string, string) {
|
|
|
|
var prefix bytes.Buffer
|
2016-11-15 20:30:34 +01:00
|
|
|
|
2017-02-10 02:26:49 +01:00
|
|
|
// Now print the message category's prefix (error/warning).
|
2017-12-14 20:53:02 +01:00
|
|
|
switch sev {
|
|
|
|
case Debug:
|
2018-05-08 00:11:52 +02:00
|
|
|
prefix.WriteString(colors.SpecDebug)
|
2017-12-14 20:53:02 +01:00
|
|
|
case Info, Infoerr:
|
2018-05-08 00:11:52 +02:00
|
|
|
prefix.WriteString(colors.SpecInfo)
|
2017-12-14 20:53:02 +01:00
|
|
|
case Error:
|
2018-05-08 00:11:52 +02:00
|
|
|
prefix.WriteString(colors.SpecError)
|
2017-12-14 20:53:02 +01:00
|
|
|
case Warning:
|
2018-05-08 00:11:52 +02:00
|
|
|
prefix.WriteString(colors.SpecWarning)
|
2017-12-14 20:53:02 +01:00
|
|
|
default:
|
|
|
|
contract.Failf("Unrecognized diagnostic severity: %v", sev)
|
2017-02-10 02:26:49 +01:00
|
|
|
}
|
|
|
|
|
2018-05-08 00:11:52 +02:00
|
|
|
prefix.WriteString(string(sev))
|
|
|
|
prefix.WriteString(": ")
|
|
|
|
prefix.WriteString(colors.Reset)
|
2017-02-10 02:26:49 +01:00
|
|
|
|
|
|
|
// Finally, actually print the message itself.
|
2018-05-08 00:11:52 +02:00
|
|
|
var buffer bytes.Buffer
|
2017-12-14 20:53:02 +01:00
|
|
|
buffer.WriteString(colors.SpecNote)
|
2016-11-15 20:30:34 +01:00
|
|
|
|
2017-11-14 20:26:41 +01:00
|
|
|
if diag.Raw {
|
|
|
|
buffer.WriteString(diag.Message)
|
|
|
|
} else {
|
|
|
|
buffer.WriteString(fmt.Sprintf(diag.Message, args...))
|
|
|
|
}
|
2017-02-10 02:26:49 +01:00
|
|
|
|
2017-12-14 20:53:02 +01:00
|
|
|
buffer.WriteString(colors.Reset)
|
2016-11-15 20:30:34 +01:00
|
|
|
buffer.WriteRune('\n')
|
|
|
|
|
2017-09-22 04:18:21 +02:00
|
|
|
// TODO[pulumi/pulumi#15]: support Clang-style expressive diagnostics. This would entail, for example, using
|
2017-08-02 18:25:22 +02:00
|
|
|
// the buffer within the target document, to demonstrate the offending line/column range of code.
|
2016-11-15 20:30:34 +01:00
|
|
|
|
2018-05-16 01:09:15 +02:00
|
|
|
// Ensure that any sensitive data we know about is filtered out preemptively.
|
|
|
|
filtered := logging.FilterString(buffer.String())
|
|
|
|
|
2017-02-10 02:26:49 +01:00
|
|
|
// If colorization was requested, compile and execute the directives now.
|
2018-05-16 01:09:15 +02:00
|
|
|
return d.opts.Color.Colorize(prefix.String()), d.opts.Color.Colorize(filtered)
|
2016-11-15 20:30:34 +01:00
|
|
|
}
|