Merge lp:~thumper/juju-core/logging-in-environment 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: 1803
Proposed branch: lp:~thumper/juju-core/logging-in-environment
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 383 lines (+134/-42)
6 files modified
cmd/logging.go (+4/-1)
cmd/logging_test.go (+47/-25)
environs/config/config.go (+25/-0)
environs/config/config_test.go (+38/-3)
juju/osenv/vars.go (+4/-3)
testing/environ.go (+16/-10)
To merge this branch: bzr merge lp:~thumper/juju-core/logging-in-environment
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+185392@code.launchpad.net

Commit message

Store logging config in the environ config.

There are two main changes here. Firstly is an environment variable for the
logging config. This provides a source for the default logging config should
none be explicity set. This is handled in two places: the Log command helper;
and the new config settings.

The second is to store the logging config in the environment config. This is
used in upcoming changes to configure the agents.

https://codereview.appspot.com/13269052/

Description of the change

Store logging config in the environ config.

There are two main changes here. Firstly is an environment variable for the
logging config. This provides a source for the default logging config should
none be explicity set. This is handled in two places: the Log command helper;
and the new config settings.

The second is to store the logging config in the environment config. This is
used in upcoming changes to configure the agents.

https://codereview.appspot.com/13269052/

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

Reviewers: mp+185392_code.launchpad.net,

Message:
Please take a look.

Description:
Store logging config in the environ config.

There are two main changes here. Firstly is an environment variable for
the
logging config. This provides a source for the default logging config
should
none be explicity set. This is handled in two places: the Log command
helper;
and the new config settings.

The second is to store the logging config in the environment config.
This is
used in upcoming changes to configure the agents.

https://code.launchpad.net/~thumper/juju-core/logging-in-environment/+merge/185392

(do not edit description out of merge proposal)

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

Affected files (+135, -42 lines):
   A [revision details]
   M cmd/logging.go
   M cmd/logging_test.go
   M environs/config/config.go
   M environs/config/config_test.go
   M juju/osenv/vars.go
   M testing/environ.go

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

LGTM but I was confused when I read "environment", as in the Juju
context, that means something different to environment variables. eg we
talk about environment constraints as being stored in the environment,
which means in state in mgo. Could you consider changing the text to
talk about environment variables?

https://codereview.appspot.com/13269052/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cmd/logging.go'
2--- cmd/logging.go 2013-09-12 08:00:07 +0000
3+++ cmd/logging.go 2013-09-13 01:27:52 +0000
4@@ -11,6 +11,8 @@
5
6 "launchpad.net/gnuflag"
7 "launchpad.net/loggo"
8+
9+ "launchpad.net/juju-core/juju/osenv"
10 )
11
12 // Log supplies the necessary functionality for Commands that wish to set up
13@@ -30,7 +32,8 @@
14 f.BoolVar(&l.Verbose, "v", false, "if set, log additional messages")
15 f.BoolVar(&l.Verbose, "verbose", false, "if set, log additional messages")
16 f.BoolVar(&l.Debug, "debug", false, "if set, log debugging messages")
17- f.StringVar(&l.Config, "log-config", "", "specify log levels for modules")
18+ defaultLogConfig := os.Getenv(osenv.JujuLoggingConfig)
19+ f.StringVar(&l.Config, "log-config", defaultLogConfig, "specify log levels for modules")
20 f.BoolVar(&l.ShowLog, "show-log", false, "if set, write the log file to stderr")
21 }
22
23
24=== modified file 'cmd/logging_test.go'
25--- cmd/logging_test.go 2013-09-12 03:54:56 +0000
26+++ cmd/logging_test.go 2013-09-13 01:27:52 +0000
27@@ -11,39 +11,61 @@
28 "launchpad.net/loggo"
29
30 "launchpad.net/juju-core/cmd"
31- "launchpad.net/juju-core/log"
32+ "launchpad.net/juju-core/juju/osenv"
33 "launchpad.net/juju-core/testing"
34 )
35
36+var logger = loggo.GetLogger("juju.test")
37+
38 type LogSuite struct {
39+ testing.CleanupSuite
40 }
41
42 var _ = gc.Suite(&LogSuite{})
43
44-func (s *LogSuite) TearDownTest(c *gc.C) {
45- loggo.ResetLoggers()
46- loggo.ResetWriters()
47+func (s *LogSuite) SetUpTest(c *gc.C) {
48+ restore := testing.PatchEnvironment(osenv.JujuLoggingConfig, "")
49+ s.AddCleanup(func() {
50+ restore()
51+ loggo.ResetLoggers()
52+ loggo.ResetWriters()
53+ })
54 }
55
56-func (s *LogSuite) TestAddFlags(c *gc.C) {
57- l := &cmd.Log{}
58- f := testing.NewFlagSet()
59- l.AddFlags(f)
60-
61- err := f.Parse(false, []string{})
62+func newLogWithFlags(c *gc.C, flags []string) *cmd.Log {
63+ log := &cmd.Log{}
64+ flagSet := testing.NewFlagSet()
65+ log.AddFlags(flagSet)
66+ err := flagSet.Parse(false, flags)
67 c.Assert(err, gc.IsNil)
68- c.Assert(l.Path, gc.Equals, "")
69- c.Assert(l.Verbose, gc.Equals, false)
70- c.Assert(l.Debug, gc.Equals, false)
71- c.Assert(l.Config, gc.Equals, "")
72-
73- err = f.Parse(false, []string{"--log-file", "foo", "--verbose", "--debug",
74+ return log
75+}
76+
77+func (s *LogSuite) TestNoFlags(c *gc.C) {
78+ log := newLogWithFlags(c, []string{})
79+ c.Assert(log.Path, gc.Equals, "")
80+ c.Assert(log.Verbose, gc.Equals, false)
81+ c.Assert(log.Debug, gc.Equals, false)
82+ c.Assert(log.Config, gc.Equals, "")
83+}
84+
85+func (s *LogSuite) TestFlags(c *gc.C) {
86+ log := newLogWithFlags(c, []string{"--log-file", "foo", "--verbose", "--debug",
87 "--log-config=juju.cmd=INFO;juju.worker.deployer=DEBUG"})
88- c.Assert(err, gc.IsNil)
89- c.Assert(l.Path, gc.Equals, "foo")
90- c.Assert(l.Verbose, gc.Equals, true)
91- c.Assert(l.Debug, gc.Equals, true)
92- c.Assert(l.Config, gc.Equals, "juju.cmd=INFO;juju.worker.deployer=DEBUG")
93+ c.Assert(log.Path, gc.Equals, "foo")
94+ c.Assert(log.Verbose, gc.Equals, true)
95+ c.Assert(log.Debug, gc.Equals, true)
96+ c.Assert(log.Config, gc.Equals, "juju.cmd=INFO;juju.worker.deployer=DEBUG")
97+}
98+
99+func (s *LogSuite) TestLogConfigFromEnvironment(c *gc.C) {
100+ config := "juju.cmd=INFO;juju.worker.deployer=DEBUG"
101+ testing.PatchEnvironment(osenv.JujuLoggingConfig, config)
102+ log := newLogWithFlags(c, []string{})
103+ c.Assert(log.Path, gc.Equals, "")
104+ c.Assert(log.Verbose, gc.Equals, false)
105+ c.Assert(log.Debug, gc.Equals, false)
106+ c.Assert(log.Config, gc.Equals, config)
107 }
108
109 func (s *LogSuite) TestVerboseSetsLogLevel(c *gc.C) {
110@@ -84,7 +106,7 @@
111 ctx := testing.Context(c)
112 err := l.Start(ctx)
113 c.Assert(err, gc.IsNil)
114- log.Infof("hello")
115+ logger.Infof("hello")
116 c.Assert(testing.Stderr(ctx), gc.Matches, `^.* INFO .* hello\n`)
117 }
118
119@@ -93,7 +115,7 @@
120 ctx := testing.Context(c)
121 err := l.Start(ctx)
122 c.Assert(err, gc.IsNil)
123- log.Infof("hello")
124+ logger.Infof("hello")
125 content, err := ioutil.ReadFile(filepath.Join(ctx.Dir, "foo.log"))
126 c.Assert(err, gc.IsNil)
127 c.Assert(string(content), gc.Matches, `^.* INFO .* hello\n`)
128@@ -107,7 +129,7 @@
129 ctx := testing.Context(c)
130 err := l.Start(ctx)
131 c.Assert(err, gc.IsNil)
132- log.Infof("hello")
133+ logger.Infof("hello")
134 c.Assert(testing.Stderr(ctx), gc.Equals, "")
135 content, err := ioutil.ReadFile(path)
136 c.Assert(err, gc.IsNil)
137@@ -119,7 +141,7 @@
138 ctx := testing.Context(c)
139 err := l.Start(ctx)
140 c.Assert(err, gc.IsNil)
141- log.Infof("hello")
142+ logger.Infof("hello")
143 content, err := ioutil.ReadFile(filepath.Join(ctx.Dir, "foo.log"))
144 c.Assert(err, gc.IsNil)
145 c.Assert(string(content), gc.Matches, `^.* INFO .* hello\n`)
146
147=== modified file 'environs/config/config.go'
148--- environs/config/config.go 2013-09-12 14:12:32 +0000
149+++ environs/config/config.go 2013-09-13 01:27:52 +0000
150@@ -14,6 +14,7 @@
151 "launchpad.net/loggo"
152
153 "launchpad.net/juju-core/cert"
154+ "launchpad.net/juju-core/juju/osenv"
155 "launchpad.net/juju-core/schema"
156 "launchpad.net/juju-core/version"
157 )
158@@ -97,6 +98,16 @@
159 return nil, err
160 }
161 }
162+ // If the logging config hasn't been set, then look for the os environment
163+ // variable, and failing that, get the config from loggo itself.
164+ if c.asString("logging-config") == "" {
165+ if environmentValue := os.Getenv(osenv.JujuLoggingConfig); environmentValue != "" {
166+ c.m["logging-config"] = environmentValue
167+ } else {
168+ c.m["logging-config"] = loggo.LoggerInfo()
169+ }
170+ }
171+
172 // no old config to compare against
173 if err = Validate(c, nil); err != nil {
174 return nil, err
175@@ -192,6 +203,13 @@
176 }
177 }
178
179+ // If the logging config is set, make sure it is valid.
180+ if v, ok := cfg.m["logging-config"].(string); ok {
181+ if _, err := loggo.ParseConfigurationString(v); err != nil {
182+ return err
183+ }
184+ }
185+
186 // Check firewall mode.
187 if mode := cfg.FirewallMode(); mode != FwInstance && mode != FwGlobal {
188 return fmt.Errorf("invalid firewall mode in environment configuration: %q", mode)
189@@ -414,6 +432,11 @@
190 return c.m["ssl-hostname-verification"].(bool)
191 }
192
193+// LoggingConfig returns the configuration string for the loggers.
194+func (c *Config) LoggingConfig() string {
195+ return c.asString("logging-config")
196+}
197+
198 // UnknownAttrs returns a copy of the raw configuration attributes
199 // that are supposedly specific to the environment type. They could
200 // also be wrong attributes, though. Only the specific environment
201@@ -463,6 +486,7 @@
202 "ssl-hostname-verification": schema.Bool(),
203 "state-port": schema.ForceInt(),
204 "api-port": schema.ForceInt(),
205+ "logging-config": schema.String(),
206 }
207
208 // alwaysOptional holds configuration defaults for attributes that may
209@@ -480,6 +504,7 @@
210 "authorized-keys-path": schema.Omit,
211 "ca-cert-path": schema.Omit,
212 "ca-private-key-path": schema.Omit,
213+ "logging-config": schema.Omit,
214
215 // For backward compatibility reasons, the following
216 // attributes default to empty strings rather than being
217
218=== modified file 'environs/config/config_test.go'
219--- environs/config/config_test.go 2013-09-09 15:09:50 +0000
220+++ environs/config/config_test.go 2013-09-13 01:27:52 +0000
221@@ -9,9 +9,11 @@
222 "time"
223
224 gc "launchpad.net/gocheck"
225+ "launchpad.net/loggo"
226
227 "launchpad.net/juju-core/cert"
228 "launchpad.net/juju-core/environs/config"
229+ "launchpad.net/juju-core/juju/osenv"
230 "launchpad.net/juju-core/schema"
231 "launchpad.net/juju-core/testing"
232 jc "launchpad.net/juju-core/testing/checkers"
233@@ -419,6 +421,15 @@
234 },
235 err: `api-port: expected number, got "illegal"`,
236 }, {
237+ about: "Invalid logging configuration",
238+ useDefaults: config.UseDefaults,
239+ attrs: testing.Attrs{
240+ "type": "my-type",
241+ "name": "my-name",
242+ "logging-config": "foo=bar",
243+ },
244+ err: `unknown severity level "bar"`,
245+ }, {
246 about: "Sample configuration",
247 useDefaults: config.UseDefaults,
248 attrs: sampleConfig,
249@@ -726,6 +737,8 @@
250 }
251
252 func (*ConfigSuite) TestConfigAttrs(c *gc.C) {
253+ // Normally this is handled by testing.FakeHome
254+ defer testing.PatchEnvironment(osenv.JujuLoggingConfig, "")()
255 attrs := map[string]interface{}{
256 "type": "my-type",
257 "name": "my-name",
258@@ -746,6 +759,7 @@
259 // These attributes are added if not set.
260 attrs["development"] = false
261 attrs["default-series"] = config.DefaultSeries
262+ attrs["logging-config"] = loggo.LoggerInfo()
263 attrs["ca-private-key"] = ""
264 attrs["image-metadata-url"] = ""
265 attrs["tools-url"] = ""
266@@ -847,12 +861,16 @@
267 }
268 }
269
270-func (*ConfigSuite) TestValidateUnknownAttrs(c *gc.C) {
271- defer testing.MakeFakeHomeWithFiles(c, []testing.TestFile{
272+func makeFakeHome(c *gc.C) *testing.FakeHome {
273+ return testing.MakeFakeHomeWithFiles(c, []testing.TestFile{
274 {".ssh/id_rsa.pub", "rsa\n"},
275 {".juju/myenv-cert.pem", caCert},
276 {".juju/myenv-private-key.pem", caKey},
277- }).Restore()
278+ })
279+}
280+
281+func (*ConfigSuite) TestValidateUnknownAttrs(c *gc.C) {
282+ defer makeFakeHome(c).Restore()
283 cfg, err := config.New(config.UseDefaults, map[string]interface{}{
284 "name": "myenv",
285 "type": "other",
286@@ -904,6 +922,23 @@
287 return result
288 }
289
290+func (*ConfigSuite) TestLoggingConfig(c *gc.C) {
291+ defer makeFakeHome(c).Restore()
292+
293+ logConfig := "<root>=WARNING;juju=DEBUG"
294+ config := newTestConfig(c, testing.Attrs{"logging-config": logConfig})
295+ c.Assert(config.LoggingConfig(), gc.Equals, logConfig)
296+}
297+
298+func (*ConfigSuite) TestLoggingConfigFromEnvironment(c *gc.C) {
299+ defer makeFakeHome(c).Restore()
300+ logConfig := "<root>=INFO"
301+ defer testing.PatchEnvironment(osenv.JujuLoggingConfig, logConfig)()
302+
303+ config := newTestConfig(c, nil)
304+ c.Assert(config.LoggingConfig(), gc.Equals, logConfig)
305+}
306+
307 func (*ConfigSuite) TestGenerateStateServerCertAndKey(c *gc.C) {
308 // In order to test missing certs, it checks the JUJU_HOME dir, so we need
309 // a fake home.
310
311=== modified file 'juju/osenv/vars.go'
312--- juju/osenv/vars.go 2013-09-11 22:12:29 +0000
313+++ juju/osenv/vars.go 2013-09-13 01:27:52 +0000
314@@ -10,9 +10,10 @@
315 )
316
317 const (
318- JujuEnv = "JUJU_ENV"
319- JujuHome = "JUJU_HOME"
320- JujuRepository = "JUJU_REPOSITORY"
321+ JujuEnv = "JUJU_ENV"
322+ JujuHome = "JUJU_HOME"
323+ JujuRepository = "JUJU_REPOSITORY"
324+ JujuLoggingConfig = "JUJU_LOGGING_CONFIG"
325 // TODO(thumper): 2013-09-02 bug 1219630
326 // As much as I'd like to remove JujuContainerType now, it is still
327 // needed as MAAS still needs it at this stage, and we can't fix
328
329=== modified file 'testing/environ.go'
330--- testing/environ.go 2013-09-12 14:16:48 +0000
331+++ testing/environ.go 2013-09-13 01:27:52 +0000
332@@ -85,8 +85,7 @@
333
334 type FakeHome struct {
335 oldHomeEnv string
336- oldJujuEnv string
337- oldJujuHomeEnv string
338+ oldEnvironment map[string]string
339 oldJujuHome string
340 files []TestFile
341 }
342@@ -142,18 +141,24 @@
343
344 func MakeEmptyFakeHomeWithoutJuju(c *C) *FakeHome {
345 oldHomeEnv := osenv.Home()
346- oldJujuHomeEnv := os.Getenv("JUJU_HOME")
347- oldJujuEnv := os.Getenv("JUJU_ENV")
348+ oldEnvironment := make(map[string]string)
349+ for _, name := range []string{
350+ osenv.JujuHome,
351+ osenv.JujuEnv,
352+ osenv.JujuLoggingConfig,
353+ } {
354+ oldEnvironment[name] = os.Getenv(name)
355+ }
356 fakeHome := c.MkDir()
357 osenv.SetHome(fakeHome)
358- os.Setenv("JUJU_HOME", "")
359- os.Setenv("JUJU_ENV", "")
360+ os.Setenv(osenv.JujuHome, "")
361+ os.Setenv(osenv.JujuEnv, "")
362+ os.Setenv(osenv.JujuLoggingConfig, "")
363 jujuHome := filepath.Join(fakeHome, ".juju")
364 oldJujuHome := config.SetJujuHome(jujuHome)
365 return &FakeHome{
366 oldHomeEnv: oldHomeEnv,
367- oldJujuEnv: oldJujuEnv,
368- oldJujuHomeEnv: oldJujuHomeEnv,
369+ oldEnvironment: oldEnvironment,
370 oldJujuHome: oldJujuHome,
371 files: []TestFile{},
372 }
373@@ -166,8 +171,9 @@
374
375 func (h *FakeHome) Restore() {
376 config.SetJujuHome(h.oldJujuHome)
377- os.Setenv("JUJU_ENV", h.oldJujuEnv)
378- os.Setenv("JUJU_HOME", h.oldJujuHomeEnv)
379+ for name, value := range h.oldEnvironment {
380+ os.Setenv(name, value)
381+ }
382 osenv.SetHome(h.oldHomeEnv)
383 }
384

Subscribers

People subscribed via source and target branches

to status/vote changes: