Merge lp:~thumper/juju-core/default-command-info into lp:~go-bot/juju-core/trunk

Proposed by Tim Penhey
Status: Merged
Approved by: Tim Penhey
Approved revision: no longer in the source branch.
Merged at revision: 2479
Proposed branch: lp:~thumper/juju-core/default-command-info
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 323 lines (+152/-39)
6 files modified
cmd/cmd.go (+34/-4)
cmd/juju/deploy.go (+2/-3)
cmd/juju/deploy_test.go (+2/-2)
cmd/juju/main_test.go (+1/-0)
cmd/logging.go (+25/-18)
cmd/logging_test.go (+88/-12)
To merge this branch: bzr merge lp:~thumper/juju-core/default-command-info
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+194061@code.launchpad.net

Commit message

Add standard functions for command output.

Add simple function support and flags around changing how the command output
works by default. Add flag options for '-q' and '--quiet'. Also updated the text for the flags.

There are now two methods on the cmd.Context object that should be used for output:
  func (ctx *Context) Infof(format string, params ...interface{})
and
  func (ctx *Context) Verbosef(format string, params ...interface{})

If quiet is specified, both are logged instead of written out. If verbose is
specified, both are written out, if the defaults are used, Info is written
out, but verbose is logged.

Description of the change

Add standard functions for command output.

Add simple function support and flags around changing how the command output
works by default. Add flag options for '-q' and '--quiet', and provider a
short '-d' for '--debug'. Also updated the text for the flags.

There are now two methods in the cmd package that should be used for output:
  cmd.Infof(...)
and
  cmd.Verbosef(...)

If quiet is specified, both are logged instead of written out. If verbose is
specified, both are written out, if the defaults are used, Info is written
out, but verbose is logged.

Ideally I'd like to tweak loggo so we can specify the call depth of the
caller, so we can grab the appropriate line numbers etc, but this can happen
later. Also, now any use of these methods will have the 'juju.cmd' module. Not
sure if we want to really parameterize that.

The only thing I'm wondering about is Stderr vs. Stdout. Ideally I'd prefer
to use Stdout where possible, but for the format oriented commands, we still
want users to be able to go:
  'juju status --format=json | other-thing'
So we don't want to polute Stdout in those situations with output.

There are a number of options here:
 * we just write to Stdout, and have people add '-q'
 * we write the info and verbose info to Stderr so it just works

Then do we have some go to Stdout and some Stderr?

Logging now goes to Stderr, so we could just send all output there (except for
the actual formatted output).

https://codereview.appspot.com/22320043/

To post a comment you must log in.
Revision history for this message
Tim Penhey (thumper) wrote :

Reviewers: mp+194061_code.launchpad.net,

Message:
Please take a look.

Description:
Add standard functions for command output.

Add simple function support and flags around changing how the command
output
works by default. Add flag options for '-q' and '--quiet', and provider
a
short '-d' for '--debug'. Also updated the text for the flags.

There are now two methods in the cmd package that should be used for
output:
   cmd.Infof(...)
and
   cmd.Verbosef(...)

If quiet is specified, both are logged instead of written out. If
verbose is
specified, both are written out, if the defaults are used, Info is
written
out, but verbose is logged.

Ideally I'd like to tweak loggo so we can specify the call depth of the
caller, so we can grab the appropriate line numbers etc, but this can
happen
later. Also, now any use of these methods will have the 'juju.cmd'
module. Not
sure if we want to really parameterize that.

The only thing I'm wondering about is Stderr vs. Stdout. Ideally I'd
prefer
to use Stdout where possible, but for the format oriented commands, we
still
want users to be able to go:
   'juju status --format=json | other-thing'
So we don't want to polute Stdout in those situations with output.

There are a number of options here:
  * we just write to Stdout, and have people add '-q'
  * we write the info and verbose info to Stderr so it just works

Then do we have some go to Stdout and some Stderr?

Logging now goes to Stderr, so we could just send all output there
(except for
the actual formatted output).

https://code.launchpad.net/~thumper/juju-core/default-command-info/+merge/194061

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/22320043/

Affected files (+139, -28 lines):
   A [revision details]
   M cmd/export_test.go
   M cmd/logging.go
   M cmd/logging_test.go

Revision history for this message
Ian Booth (wallyworld) wrote :

A few questions.

1. -d for debug is sorta bad

There's a number of existing commands that use the -d option (eg for
specifying a directory) so I think we want to stcik with just --debug

2. Does it make sense to allow -q and --debug together?

If you want debug, then I think you would want everything else as well

3. show-log

I think if verbose is specified, that could turn on show-log. Do we
still need show-log? I'm not sure we do. For a user's perspective, I
want to see either:

i. nothing at all except errors... option = "--quiet"
ii. informational lines that signpost where the command is up to as it
executes (without timestamps etc)... the default, option = ""
iii. verbose output with timestamps and some more detail... option =
"--verbose"

As a developer, I also want:

iv. debug output with everything... option = "--debug"

I'm not sure with the above if show-log is still relevant.

As for the stdout vs stderr thing, I can see both sides. My initial view
is that stderr is for all log outout and stdout is for command results
in json/yaml etc

https://codereview.appspot.com/22320043/diff/1/cmd/logging.go
File cmd/logging.go (right):

https://codereview.appspot.com/22320043/diff/1/cmd/logging.go#newcode77
cmd/logging.go:77: return fmt.Errorf(`"verbose" and "quiet" flags
clash`)
perhaps

"verbose" and "quiet" flags clash, please use one or the other, not both

https://codereview.appspot.com/22320043/

Revision history for this message
William Reade (fwereade) wrote :

On 2013/11/06 04:04:42, thumper wrote:
> Please take a look.

I'm sure we want to keep informational messages to stderr. Still
thinking about the other points raised.

https://codereview.appspot.com/22320043/

Revision history for this message
John A Meinel (jameinel) wrote :

We have a cmd.Context object which is passed to all the commands, and is
something that we can then pass into internal code.

It seems better to have it on an object, rather than as a package level
function.

does that make sense to you?

https://codereview.appspot.com/22320043/

Revision history for this message
William Reade (fwereade) wrote :

On 2013/11/06 11:45:34, jameinel wrote:
> We have a cmd.Context object which is passed to all the commands, and
is
> something that we can then pass into internal code.

> It seems better to have it on an object, rather than as a package
level
> function.

> does that make sense to you?

That's actually starting to make more and more sense, because:

1) the value of this gets lower and lower as more functionality moves
behind the API -- it becomes more and more convenient to just write to
the cmd.Context that's right there in Run

2) bootstrap and (manual) add-machine feel like the major exceptions to
the above, but both of those need the context anyway for sudo (and given
that we probably ought not to be reading env vars directly, we probably
ought to be communicating those to bootstrap via some such context too).

What's the actual set of potential users for this code once the CLI
talks API?

https://codereview.appspot.com/22320043/

Revision history for this message
William Reade (fwereade) wrote :

WIPping -- any further thoughts, tim?

Revision history for this message
Tim Penhey (thumper) wrote :
Revision history for this message
Tim Penhey (thumper) wrote :

On 2013/11/06 04:31:25, wallyworld wrote:
> A few questions.

> 1. -d for debug is sorta bad

> There's a number of existing commands that use the -d option (eg for
specifying
> a directory) so I think we want to stcik with just --debug

Removed -d

> 2. Does it make sense to allow -q and --debug together?

> If you want debug, then I think you would want everything else as well

Yes -q and --debug is fine (IMO). In fact I force the fact, as if you
say
--debug, by forcing -q we get all the info, and verbose output as log
file
entries.

> 3. show-log

> I think if verbose is specified, that could turn on show-log. Do we
still need
> show-log? I'm not sure we do. For a user's perspective, I want to see
either:

> i. nothing at all except errors... option = "--quiet"
> ii. informational lines that signpost where the command is up to as it
executes
> (without timestamps etc)... the default, option = ""
> iii. verbose output with timestamps and some more detail... option =
"--verbose"

> As a developer, I also want:

> iv. debug output with everything... option = "--debug"

> I'm not sure with the above if show-log is still relevant.

Perhaps not... but outside the scope of this for now.

> As for the stdout vs stderr thing, I can see both sides. My initial
view is that
> stderr is for all log outout and stdout is for command results in
json/yaml etc

> https://codereview.appspot.com/22320043/diff/1/cmd/logging.go
> File cmd/logging.go (right):

https://codereview.appspot.com/22320043/diff/1/cmd/logging.go#newcode77
> cmd/logging.go:77: return fmt.Errorf(`"verbose" and "quiet" flags
clash`)
> perhaps

> "verbose" and "quiet" flags clash, please use one or the other, not
both

done

https://codereview.appspot.com/22320043/

Revision history for this message
Tim Penhey (thumper) wrote :

On 2013/11/06 10:44:31, fwereade wrote:
> On 2013/11/06 04:04:42, thumper wrote:
> > Please take a look.

> I'm sure we want to keep informational messages to stderr. Still
thinking about
> the other points raised.

kept them on stderr

https://codereview.appspot.com/22320043/

Revision history for this message
Tim Penhey (thumper) wrote :

On 2013/11/06 11:45:34, jameinel wrote:
> We have a cmd.Context object which is passed to all the commands, and
is
> something that we can then pass into internal code.

> It seems better to have it on an object, rather than as a package
level
> function.

> does that make sense to you?

moved the methods to the context object.

I had originally thought that by having them as stand alone functions,
we wouldn't have to pass the context down to the places that are needing
them.

Consider the bastardisation we have with loggers at the moment.

https://codereview.appspot.com/22320043/

Revision history for this message
Ian Booth (wallyworld) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'cmd/cmd.go'
--- cmd/cmd.go 2014-03-24 13:23:40 +0000
+++ cmd/cmd.go 2014-03-26 01:26:35 +0000
@@ -90,10 +90,40 @@
90// should interpret file names relative to Dir (see AbsPath below), and print90// should interpret file names relative to Dir (see AbsPath below), and print
91// output and errors to Stdout and Stderr respectively.91// output and errors to Stdout and Stderr respectively.
92type Context struct {92type Context struct {
93 Dir string93 Dir string
94 Stdin io.Reader94 Stdin io.Reader
95 Stdout io.Writer95 Stdout io.Writer
96 Stderr io.Writer96 Stderr io.Writer
97 quiet bool
98 verbose bool
99}
100
101func (ctx *Context) write(format string, params ...interface{}) {
102 output := fmt.Sprintf(format, params...)
103 if !strings.HasSuffix(output, "\n") {
104 output = output + "\n"
105 }
106 fmt.Fprint(ctx.Stderr, output)
107}
108
109// Infof will write the formatted string to Stderr if quiet is false, but if
110// quiet is true the message is logged.
111func (ctx *Context) Infof(format string, params ...interface{}) {
112 if ctx.quiet {
113 logger.Infof(format, params...)
114 } else {
115 ctx.write(format, params...)
116 }
117}
118
119// Verbosef will write the formatted string to Stderr if the verbose is true,
120// and to the logger if not.
121func (ctx *Context) Verbosef(format string, params ...interface{}) {
122 if ctx.verbose {
123 ctx.write(format, params...)
124 } else {
125 logger.Infof(format, params...)
126 }
97}127}
98128
99// AbsPath returns an absolute representation of path, with relative paths129// AbsPath returns an absolute representation of path, with relative paths
100130
=== modified file 'cmd/juju/deploy.go'
--- cmd/juju/deploy.go 2014-03-18 05:08:25 +0000
+++ cmd/juju/deploy.go 2014-03-26 01:26:35 +0000
@@ -150,7 +150,7 @@
150 }150 }
151151
152 if c.BumpRevision {152 if c.BumpRevision {
153 ctx.Stdout.Write([]byte("--upgrade (or -u) is deprecated and ignored; charms are always deployed with a unique revision.\n"))153 ctx.Infof("--upgrade (or -u) is deprecated and ignored; charms are always deployed with a unique revision.")
154 }154 }
155155
156 charmInfo, err := client.CharmInfo(curl.String())156 charmInfo, err := client.CharmInfo(curl.String())
@@ -293,7 +293,6 @@
293 default:293 default:
294 return nil, fmt.Errorf("unsupported charm URL schema: %q", curl.Schema)294 return nil, fmt.Errorf("unsupported charm URL schema: %q", curl.Schema)
295 }295 }
296 report := fmt.Sprintf("Added charm %q to the environment.\n", curl)296 ctx.Infof("Added charm %q to the environment.", curl)
297 ctx.Stdout.Write([]byte(report))
298 return curl, nil297 return curl, nil
299}298}
300299
=== modified file 'cmd/juju/deploy_test.go'
--- cmd/juju/deploy_test.go 2014-03-13 07:54:56 +0000
+++ cmd/juju/deploy_test.go 2014-03-26 01:26:35 +0000
@@ -83,8 +83,8 @@
83 ctx, err := coretesting.RunCommand(c, &DeployCommand{}, []string{"local:dummy", "-u"})83 ctx, err := coretesting.RunCommand(c, &DeployCommand{}, []string{"local:dummy", "-u"})
84 c.Assert(err, gc.IsNil)84 c.Assert(err, gc.IsNil)
8585
86 c.Assert(coretesting.Stderr(ctx), gc.Equals, "")86 c.Assert(coretesting.Stdout(ctx), gc.Equals, "")
87 output := strings.Split(coretesting.Stdout(ctx), "\n")87 output := strings.Split(coretesting.Stderr(ctx), "\n")
88 c.Check(output[0], gc.Matches, `Added charm ".*" to the environment.`)88 c.Check(output[0], gc.Matches, `Added charm ".*" to the environment.`)
89 c.Check(output[1], gc.Equals, "--upgrade (or -u) is deprecated and ignored; charms are always deployed with a unique revision.")89 c.Check(output[1], gc.Equals, "--upgrade (or -u) is deprecated and ignored; charms are always deployed with a unique revision.")
90}90}
9191
=== modified file 'cmd/juju/main_test.go'
--- cmd/juju/main_test.go 2014-02-27 05:22:46 +0000
+++ cmd/juju/main_test.go 2014-03-26 01:26:35 +0000
@@ -316,6 +316,7 @@
316 "-h, --help .*",316 "-h, --help .*",
317 "--log-file .*",317 "--log-file .*",
318 "--logging-config .*",318 "--logging-config .*",
319 "-q, --quiet .*",
319 "--show-log .*",320 "--show-log .*",
320 "-v, --verbose .*",321 "-v, --verbose .*",
321}322}
322323
=== modified file 'cmd/logging.go'
--- cmd/logging.go 2014-03-05 19:41:34 +0000
+++ cmd/logging.go 2014-03-26 01:26:35 +0000
@@ -26,6 +26,7 @@
26type Log struct {26type Log struct {
27 Path string27 Path string
28 Verbose bool28 Verbose bool
29 Quiet bool
29 Debug bool30 Debug bool
30 ShowLog bool31 ShowLog bool
31 Config string32 Config string
@@ -43,45 +44,51 @@
43// AddFlags adds appropriate flags to f.44// AddFlags adds appropriate flags to f.
44func (l *Log) AddFlags(f *gnuflag.FlagSet) {45func (l *Log) AddFlags(f *gnuflag.FlagSet) {
45 f.StringVar(&l.Path, "log-file", "", "path to write log to")46 f.StringVar(&l.Path, "log-file", "", "path to write log to")
46 // TODO(thumper): rename verbose to --show-log47 f.BoolVar(&l.Verbose, "v", false, "show more verbose output")
47 f.BoolVar(&l.Verbose, "v", false, "if set, log additional messages")48 f.BoolVar(&l.Verbose, "verbose", false, "show more verbose output")
48 f.BoolVar(&l.Verbose, "verbose", false, "if set, log additional messages")49 f.BoolVar(&l.Quiet, "q", false, "show no informational output")
49 f.BoolVar(&l.Debug, "debug", false, "if set, log debugging messages")50 f.BoolVar(&l.Quiet, "quiet", false, "show no informational output")
51 f.BoolVar(&l.Debug, "debug", false, "equivalent to --show-log --log-config=<root>=DEBUG")
50 defaultLogConfig := os.Getenv(osenv.JujuLoggingConfigEnvKey)52 defaultLogConfig := os.Getenv(osenv.JujuLoggingConfigEnvKey)
51 f.StringVar(&l.Config, "logging-config", defaultLogConfig, "specify log levels for modules")53 f.StringVar(&l.Config, "logging-config", defaultLogConfig, "specify log levels for modules")
52 f.BoolVar(&l.ShowLog, "show-log", false, "if set, write the log file to stderr")54 f.BoolVar(&l.ShowLog, "show-log", false, "if set, write the log file to stderr")
53}55}
5456
55// Start starts logging using the given Context.57// Start starts logging using the given Context.
56func (l *Log) Start(ctx *Context) error {58func (log *Log) Start(ctx *Context) error {
57 if l.Path != "" {59 if log.Verbose && log.Quiet {
58 path := ctx.AbsPath(l.Path)60 return fmt.Errorf(`"verbose" and "quiet" flags clash, please use one or the other, not both`)
61 }
62 ctx.quiet = log.Quiet
63 ctx.verbose = log.Verbose
64 if log.Path != "" {
65 path := ctx.AbsPath(log.Path)
59 target, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)66 target, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
60 if err != nil {67 if err != nil {
61 return err68 return err
62 }69 }
63 writer := l.GetLogWriter(target)70 writer := log.GetLogWriter(target)
64 err = loggo.RegisterWriter("logfile", writer, loggo.TRACE)71 err = loggo.RegisterWriter("logfile", writer, loggo.TRACE)
65 if err != nil {72 if err != nil {
66 return err73 return err
67 }74 }
68 }75 }
69 level := loggo.WARNING76 level := loggo.WARNING
70 if l.Verbose {77 if log.ShowLog {
71 ctx.Stdout.Write([]byte("Flag --verbose is deprecated with the current meaning, use --show-log\n"))
72 l.ShowLog = true
73 }
74 if l.ShowLog {
75 level = loggo.INFO78 level = loggo.INFO
76 }79 }
77 if l.Debug {80 if log.Debug {
78 l.ShowLog = true81 log.ShowLog = true
79 level = loggo.DEBUG82 level = loggo.DEBUG
83 // override quiet or verbose if set, this way all the information goes
84 // to the log file.
85 ctx.quiet = true
86 ctx.verbose = false
80 }87 }
8188
82 if l.ShowLog {89 if log.ShowLog {
83 // We replace the default writer to use ctx.Stderr rather than os.Stderr.90 // We replace the default writer to use ctx.Stderr rather than os.Stderr.
84 writer := l.GetLogWriter(ctx.Stderr)91 writer := log.GetLogWriter(ctx.Stderr)
85 _, err := loggo.ReplaceDefaultWriter(writer)92 _, err := loggo.ReplaceDefaultWriter(writer)
86 if err != nil {93 if err != nil {
87 return err94 return err
@@ -99,7 +106,7 @@
99 // Set the level on the root logger.106 // Set the level on the root logger.
100 loggo.GetLogger("").SetLogLevel(level)107 loggo.GetLogger("").SetLogLevel(level)
101 // Override the logging config with specified logging config.108 // Override the logging config with specified logging config.
102 loggo.ConfigureLoggers(l.Config)109 loggo.ConfigureLoggers(log.Config)
103 return nil110 return nil
104}111}
105112
106113
=== modified file 'cmd/logging_test.go'
--- cmd/logging_test.go 2014-03-18 15:43:41 +0000
+++ cmd/logging_test.go 2014-03-26 01:26:35 +0000
@@ -25,6 +25,7 @@
25var _ = gc.Suite(&LogSuite{})25var _ = gc.Suite(&LogSuite{})
2626
27func (s *LogSuite) SetUpTest(c *gc.C) {27func (s *LogSuite) SetUpTest(c *gc.C) {
28 s.CleanupSuite.SetUpTest(c)
28 s.PatchEnvironment(osenv.JujuLoggingConfigEnvKey, "")29 s.PatchEnvironment(osenv.JujuLoggingConfigEnvKey, "")
29 s.AddCleanup(func(_ *gc.C) {30 s.AddCleanup(func(_ *gc.C) {
30 loggo.ResetLoggers()31 loggo.ResetLoggers()
@@ -44,6 +45,7 @@
44func (s *LogSuite) TestNoFlags(c *gc.C) {45func (s *LogSuite) TestNoFlags(c *gc.C) {
45 log := newLogWithFlags(c, []string{})46 log := newLogWithFlags(c, []string{})
46 c.Assert(log.Path, gc.Equals, "")47 c.Assert(log.Path, gc.Equals, "")
48 c.Assert(log.Quiet, gc.Equals, false)
47 c.Assert(log.Verbose, gc.Equals, false)49 c.Assert(log.Verbose, gc.Equals, false)
48 c.Assert(log.Debug, gc.Equals, false)50 c.Assert(log.Debug, gc.Equals, false)
49 c.Assert(log.Config, gc.Equals, "")51 c.Assert(log.Config, gc.Equals, "")
@@ -68,17 +70,6 @@
68 c.Assert(log.Config, gc.Equals, config)70 c.Assert(log.Config, gc.Equals, config)
69}71}
7072
71func (s *LogSuite) TestVerboseSetsLogLevel(c *gc.C) {
72 l := &cmd.Log{Verbose: true}
73 ctx := coretesting.Context(c)
74 err := l.Start(ctx)
75 c.Assert(err, gc.IsNil)
76
77 c.Assert(loggo.GetLogger("").LogLevel(), gc.Equals, loggo.INFO)
78 c.Assert(coretesting.Stderr(ctx), gc.Equals, "")
79 c.Assert(coretesting.Stdout(ctx), gc.Equals, "Flag --verbose is deprecated with the current meaning, use --show-log\n")
80}
81
82func (s *LogSuite) TestDebugSetsLogLevel(c *gc.C) {73func (s *LogSuite) TestDebugSetsLogLevel(c *gc.C) {
83 l := &cmd.Log{Debug: true}74 l := &cmd.Log{Debug: true}
84 ctx := coretesting.Context(c)75 ctx := coretesting.Context(c)
@@ -102,7 +93,7 @@
102}93}
10394
104func (s *LogSuite) TestStderr(c *gc.C) {95func (s *LogSuite) TestStderr(c *gc.C) {
105 l := &cmd.Log{Verbose: true, Config: "<root>=INFO"}96 l := &cmd.Log{ShowLog: true, Config: "<root>=INFO"}
106 ctx := coretesting.Context(c)97 ctx := coretesting.Context(c)
107 err := l.Start(ctx)98 err := l.Start(ctx)
108 c.Assert(err, gc.IsNil)99 c.Assert(err, gc.IsNil)
@@ -161,3 +152,88 @@
161 c.Assert(coretesting.Stderr(ctx), gc.Matches, `^.*WARNING a warning\n.*ERROR an error\n.*`)152 c.Assert(coretesting.Stderr(ctx), gc.Matches, `^.*WARNING a warning\n.*ERROR an error\n.*`)
162 c.Assert(coretesting.Stdout(ctx), gc.Equals, "")153 c.Assert(coretesting.Stdout(ctx), gc.Equals, "")
163}154}
155
156func (s *LogSuite) TestQuietAndVerbose(c *gc.C) {
157 l := &cmd.Log{Verbose: true, Quiet: true}
158 ctx := coretesting.Context(c)
159 err := l.Start(ctx)
160 c.Assert(err, gc.ErrorMatches, `"verbose" and "quiet" flags clash, please use one or the other, not both`)
161}
162
163func (s *LogSuite) TestOutputDefault(c *gc.C) {
164 l := &cmd.Log{}
165 ctx := coretesting.Context(c)
166 err := l.Start(ctx)
167 c.Assert(err, gc.IsNil)
168
169 ctx.Infof("Writing info output")
170 ctx.Verbosef("Writing verbose output")
171
172 c.Assert(coretesting.Stderr(ctx), gc.Equals, "Writing info output\n")
173}
174
175func (s *LogSuite) TestOutputVerbose(c *gc.C) {
176 l := &cmd.Log{Verbose: true}
177 ctx := coretesting.Context(c)
178 err := l.Start(ctx)
179 c.Assert(err, gc.IsNil)
180
181 ctx.Infof("Writing info output")
182 ctx.Verbosef("Writing verbose output")
183
184 c.Assert(coretesting.Stderr(ctx), gc.Equals, "Writing info output\nWriting verbose output\n")
185}
186
187func (s *LogSuite) TestOutputQuiet(c *gc.C) {
188 l := &cmd.Log{Quiet: true}
189 ctx := coretesting.Context(c)
190 err := l.Start(ctx)
191 c.Assert(err, gc.IsNil)
192
193 ctx.Infof("Writing info output")
194 ctx.Verbosef("Writing verbose output")
195
196 c.Assert(coretesting.Stderr(ctx), gc.Equals, "")
197}
198
199func (s *LogSuite) TestOutputQuietLogs(c *gc.C) {
200 l := &cmd.Log{Quiet: true, Path: "foo.log", Config: "<root>=INFO"}
201 ctx := coretesting.Context(c)
202 err := l.Start(ctx)
203 c.Assert(err, gc.IsNil)
204
205 ctx.Infof("Writing info output")
206 ctx.Verbosef("Writing verbose output")
207
208 content, err := ioutil.ReadFile(filepath.Join(ctx.Dir, "foo.log"))
209 c.Assert(err, gc.IsNil)
210 c.Assert(coretesting.Stderr(ctx), gc.Equals, "")
211 c.Assert(string(content), gc.Matches, `^.*INFO .* Writing info output\n.*INFO .*Writing verbose output\n.*`)
212}
213
214func (s *LogSuite) TestOutputDefaultLogsVerbose(c *gc.C) {
215 l := &cmd.Log{Path: "foo.log", Config: "<root>=INFO"}
216 ctx := coretesting.Context(c)
217 err := l.Start(ctx)
218 c.Assert(err, gc.IsNil)
219
220 ctx.Infof("Writing info output")
221 ctx.Verbosef("Writing verbose output")
222
223 content, err := ioutil.ReadFile(filepath.Join(ctx.Dir, "foo.log"))
224 c.Assert(err, gc.IsNil)
225 c.Assert(coretesting.Stderr(ctx), gc.Equals, "Writing info output\n")
226 c.Assert(string(content), gc.Matches, `^.*INFO .*Writing verbose output\n.*`)
227}
228
229func (s *LogSuite) TestOutputDebugForcesQuiet(c *gc.C) {
230 l := &cmd.Log{Verbose: true, Debug: true}
231 ctx := coretesting.Context(c)
232 err := l.Start(ctx)
233 c.Assert(err, gc.IsNil)
234
235 ctx.Infof("Writing info output")
236 ctx.Verbosef("Writing verbose output")
237
238 c.Assert(coretesting.Stderr(ctx), gc.Matches, `^.*INFO .* Writing info output\n.*INFO .*Writing verbose output\n.*`)
239}

Subscribers

People subscribed via source and target branches

to status/vote changes: