Skip to content

Commit ce12c08

Browse files
author
Glyn Normington
committed
Create a basic logging framework for the buildpack
This consists of a LoggerFactory class in a Diagnostics module. The module also contains some common constants and a method to determine the diagnostics directory The LoggerFactory class manages a single instance of a subclass of the standard Ruby Logger. In normal usage, only one logger should be created: logger = LoggerFactory.create_logger(app_dir) The created logger can be retrieved from the LoggerFactory to avoid having to pass it around: logger = LoggerFactory.get_logger Logging follows the style of the standard Ruby logger, which supports both parameter and block forms: logger.info('success') logger.debug { "#{costly_method}" } The logging level is configured by setting an environment variable JBP_LOG_LEVEL to one of: DEBUG | INFO | WARN | ERROR | FATAL The default value if JBP_LOG_LEVEL is not set is configured in config/logging.yml for consistency with other buildpack configuration and in case someone wants to change it in a fork of the buildpack. If JBP_LOG_LEVEL is set to an unrecognised value, the logging level is set to DEBUG for safety (for instance, the user may have guessed that TRACE is a valid value). The logging level in JBP_LOG_LEVEL or config/logging.yml may be specified using any mixture of upper and lower case. Ruby's verbose and debug modes overrides the default logging level in config/logging.yml to DEBUG. However, JBP_LOG_LEVEL still takes priority. Log entries are written to both app/.buildpack- diagnostics/buildpack.log and $stderr. Log entries are verbose and include full details of the caller such as the full path of the Ruby program making the call. Set $stderr to synchronous writing. Introduce debug logging of stack traces. Introduce a Buildpack.drive_buildpack_with_logger method to create a logger and then yield a new Buildpack instance to the given block. Make the Buildpack constructor private so it cannot be called from elsewhere. This ensures that any Buildpack instance has a logger available to it. Create a logger in the spec helper to ensure that any class under test which needs a logger will have one. The LoggerFactory tests override this by re-creating the logger. Issue warnings if the logger is re-created, but suppress these warnings when testing the LoggerFactory and the Buildpack classes. Remove the diagnostic directory from the buildpack context Substitute the buildpack.log filename into killjava script rather than hard-coding it. Link to stackoverflow article on installing gems in support of the RubyMine debugger. [#52775343]
1 parent 159d18b commit ce12c08

17 files changed

Lines changed: 756 additions & 259 deletions

File tree

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ The buildpack supports configuration and extension through the use of Git reposi
3939
* [Frameworks](docs/extending-frameworks.md)
4040
* Utilities
4141
* [Caches](docs/util-caches.md)
42+
* [Logging](docs/logging.md)
4243
* [Repositories](docs/util-repositories.md)
4344
* [Repository Builders](docs/util-repository-builders.md)
4445
* [Test Applications](docs/util-test-applications.md)
@@ -51,6 +52,10 @@ bundle install
5152
bundle exec rake
5253
```
5354

55+
If you want to use the RubyMine debugger, you may need to [install additional gems][].
56+
57+
[install additional gems]: http://stackoverflow.com/questions/11732715/how-do-i-install-ruby-debug-base19x-on-mountain-lion-for-intellij
58+
5459
## Contributing
5560
[Pull requests][] are welcome; see the [contributor guidelines][] for details.
5661

bin/compile

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,11 @@
1616
# limitations under the License.
1717

1818
$stdout.sync = true
19+
$stderr.sync = true
1920
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2021

2122
require 'java_buildpack/buildpack'
2223

2324
build_dir = ARGV[0]
2425

25-
begin
26-
JavaBuildpack::Buildpack.new(build_dir).compile
27-
rescue => e
28-
puts "Compile failed with exception #{e.inspect}, #{e.backtrace}\n"
29-
abort e.message
30-
end
31-
26+
JavaBuildpack::Buildpack.drive_buildpack_with_logger(build_dir, 'Compile failed with exception %s') { |buildpack| buildpack.compile }

bin/detect

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,18 @@
1616
# limitations under the License.
1717

1818
$stdout.sync = true
19+
$stderr.sync = true
1920
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2021

2122
require 'java_buildpack/buildpack'
2223

2324
build_dir = ARGV[0]
2425

25-
begin
26-
components = JavaBuildpack::Buildpack.new(build_dir).detect.compact
26+
components = JavaBuildpack::Buildpack.drive_buildpack_with_logger(build_dir, 'Detect failed with exception %s') { |buildpack| buildpack.detect }.compact
2727

28-
if components.empty?
29-
abort
30-
else
31-
puts components.join(', ')
32-
end
33-
34-
rescue => e
35-
puts "Detect failed with exception #{e.inspect}, #{e.backtrace}\n"
36-
abort e.message
28+
if components.empty?
29+
abort
30+
else
31+
puts components.join(', ')
3732
end
3833

bin/release

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,11 @@
1616
# limitations under the License.
1717

1818
$stdout.sync = true
19+
$stderr.sync = true
1920
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2021

2122
require 'java_buildpack/buildpack'
2223

2324
build_dir = ARGV[0]
2425

25-
begin
26-
puts JavaBuildpack::Buildpack.new(build_dir).release
27-
rescue => e
28-
puts "Release failed with exception #{e.inspect}, #{e.backtrace}\n"
29-
abort e.message
30-
end
31-
26+
puts JavaBuildpack::Buildpack.drive_buildpack_with_logger(build_dir, 'Release failed with exception %s') { |buildpack| buildpack.release }

config/logging.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Cloud Foundry Java Buildpack
2+
# Copyright (c) 2013 the original author or authors.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# Logging configuration
17+
---
18+
default_log_level: INFO

docs/logging.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Logging
2+
3+
The Java buildpack logs to both
4+
`<app dir>/.buildpack-diagnostics/buildpack.log` and standard error.
5+
Logs are filtered according to the configured log level.
6+
7+
If the buildpack fails with an exception, the exception message is logged with a
8+
log level of `ERROR` whereas the exception stack trace is logged with a log
9+
level of `DEBUG` to prevent users from seeing stack traces by default.
10+
11+
## Logger Usage
12+
The `LoggerFactory` class in the `JavaBuildpack::Diagnostics` module
13+
manages a single instance of a subclass of the standard Ruby `Logger`.
14+
In normal usage, the `Buildpack` class creates a logger which is shared
15+
by all other classes and which is retrieved from the `LoggerFactory` as necessary:
16+
17+
logger = LoggerFactory.get_logger
18+
19+
This logger is used like the standard Ruby logger and supports
20+
both parameter and block forms:
21+
22+
logger.info('success')
23+
logger.debug { "#{costly_method}" }
24+
25+
## Configuration
26+
The log level is configured by setting an environment variable
27+
`$JBP_LOG_LEVEL` to one of:
28+
29+
DEBUG | INFO | WARN | ERROR | FATAL
30+
31+
For example:
32+
33+
cf set-env <app name> JBP_LOG_LEVEL DEBUG
34+
35+
If `JBP_LOG_LEVEL` is not set, the default log level is read from the configuration in
36+
`config/logging.yml`.
37+
38+
The logging levels in `JBP_LOG_LEVEL` and `config/logging.yml` may be
39+
specified using any mixture of upper and lower case.
40+
41+
Ruby's verbose and debug modes override the default log level to `DEBUG` unless
42+
`JBP_LOG_LEVEL` has been set, in which case this takes priority.

0 commit comments

Comments
 (0)