|
1 | 1 | # dataworks-common-logging |
2 | 2 | Kotlin utility library to be used in Dataworks applications to ensure common logging format. |
| 3 | + |
| 4 | +## Log formatting |
| 5 | +Dataworks common logging provides opinionated ways to write messages into log files, using [sl4j](http://www.slf4j.org/). |
| 6 | + |
| 7 | +Out of the box, it provides functionality to convert log messages to JSON and appends a number of common fields. These can be found in the `LogField` enum class. Any `LogField` which is not found at runtime gets set to a default value, also defined in that enum. Some example variable values are as follows: |
| 8 | + |
| 9 | +| Variable | Example value | |
| 10 | +|----------------|----------------| |
| 11 | +| environment | development | |
| 12 | +| application | my-special-api | |
| 13 | +| app_version | v1 | |
| 14 | +| component | read-from-x | |
| 15 | +| correlation_id | 1 | |
| 16 | +| hostname | 127.0.0.1 | |
| 17 | + |
| 18 | +## Using in projects |
| 19 | +To include this library in your project you will need to include the compiled this projects`.jar` file. You are also required to add a logback XML file in the resources for your project, and add the following code as an `appender`. This will inform the logging framework to use `LoggerLayoutAppender` to parse messages into our format. |
| 20 | +```xml |
| 21 | + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> |
| 22 | + <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> |
| 23 | + <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> |
| 24 | + <layout class="app.utils.logging.LoggerLayoutAppender"/> |
| 25 | + </encoder> |
| 26 | + </appender> |
| 27 | +``` |
| 28 | + |
| 29 | +## Custom fields in log messages |
| 30 | +For the case where you would like to add custom values to the logging lines which are output, `LogFields` provides functionality to do this. |
| 31 | +```kotlin |
| 32 | +LogFields.put("custom_env_var", "default value") |
| 33 | +val customLogField = LogFields.get("custom_env_var") |
| 34 | +``` |
| 35 | +This functionality is ideal for use cases where an application would like to present information which is specific to its running. |
| 36 | + |
| 37 | +Values associated to the custom variables are resolved in the same manner as common fields, i.e: |
| 38 | +1. Environment variable with the specified name |
| 39 | +2. Java System property with the specified name |
| 40 | +3. Default value provided to `LogFields.put()` |
| 41 | + |
| 42 | +Log lines output with custom fields look like the following (without pretty printing): |
| 43 | +```json |
| 44 | +{ |
| 45 | + "timestamp": "1970-04-25T07:29:03.210", |
| 46 | + "log_level": "WARN", |
| 47 | + "message": "some message about stuff", |
| 48 | + "customKey1": "Custom value 1", |
| 49 | + "customKey2": "Custom value 2", |
| 50 | + "thread": "my.thread.is.betty", |
| 51 | + "logger": "logger.name.is.mavis", |
| 52 | + "duration_in_milliseconds": "-1573885286308", |
| 53 | + "environment": "test", |
| 54 | + "application": "tests", |
| 55 | + "app_version": "v1", |
| 56 | + "component": "tests", |
| 57 | + "correlation_id": "1", |
| 58 | + "hostname": "127.0.0.1" |
| 59 | +} |
| 60 | +``` |
| 61 | + |
| 62 | +## Example log calls |
| 63 | +Below are some examples of how you can use the library to output logs. |
| 64 | + |
| 65 | +##### Including a DataworksLogger in a class |
| 66 | +```kotlin |
| 67 | +companion object { |
| 68 | + val logger = DataworksLogger.getLogger("thisClass") |
| 69 | +} |
| 70 | +``` |
| 71 | + |
| 72 | +##### Writing a log at DEBUG for data output program |
| 73 | +```kotlin |
| 74 | +val logger = DataworksLogger.getLogger("thisClass") |
| 75 | + |
| 76 | +// Using Kotlin-like syntax (preferred): |
| 77 | +logger.debug("Written manifest", "attempt_number" to "${attempts + 1}", "manifest_size" to "$manifestSize", "s3_location" to "s3://$manifestBucket/$manifestPrefix/$manifestFileName") |
| 78 | + |
| 79 | +// Using Java-like syntax |
| 80 | +logger.debug("Written manifest", Pair("attempt_number", "${attempts + 1}"), Pair("manifest_size", "$manifestSize"), Pair("s3_location", "s3://$manifestBucket/$manifestPrefix/$manifestFileName")) |
| 81 | +``` |
| 82 | + |
| 83 | +## Outputs |
| 84 | +Some example outputs are displayed below. Note that in actuality these will be on a single line, the formatting here is shown for ease of reading. |
| 85 | +##### Fully populated |
| 86 | +```json |
| 87 | +{ |
| 88 | + "timestamp": "1970-04-25T07:29:03.210", |
| 89 | + "log_level": "WARN", |
| 90 | + "message": "some message about stuff", |
| 91 | + "thread": "my.thread.is.betty", |
| 92 | + "logger": "logger.name.is.mavis", |
| 93 | + "duration_in_milliseconds": "-1573885286308", |
| 94 | + "environment": "test", |
| 95 | + "application": "tests", |
| 96 | + "app_version": "v1", |
| 97 | + "component": "tests", |
| 98 | + "correlation_id": "1", |
| 99 | + "hostname": "127.0.0.1" |
| 100 | +} |
| 101 | +``` |
| 102 | + |
| 103 | +##### With thrown exception |
| 104 | +```json |
| 105 | +{ |
| 106 | + "timestamp": "1970-04-25T07:29:03.210", |
| 107 | + "log_level": "WARN", |
| 108 | + "message": "some message about stuff", |
| 109 | + "exception": "java.lang.RuntimeException: boom1 - \/:'!@\u00A3$%^&*() | at <omitted> | at <omitted> | ... 89 common frames omitted", |
| 110 | + "thread": "my.thread.is.betty", |
| 111 | + "logger": "logger.name.is.mavis", |
| 112 | + "duration_in_milliseconds": "-1573885286308", |
| 113 | + "environment": "test", |
| 114 | + "application": "tests", |
| 115 | + "app_version": "v1", |
| 116 | + "component": "tests", |
| 117 | + "correlation_id": "1", |
| 118 | + "hostname": "127.0.0.1" |
| 119 | +} |
| 120 | +``` |
| 121 | + |
0 commit comments