Skip to content

Commit

Permalink
Updated Readme (#88)
Browse files Browse the repository at this point in the history
* Updated initialization steps
* Removed technical documentation until we can determine where it lives
* Updated tech doc location and interfaces section
* Fixed bullet points
* Update coda links to public pages
* Removed reference to ThrowableBlocker
  • Loading branch information
ssawchenko authored Sep 21, 2021
1 parent 7b477a7 commit eff8b48
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 126 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on the Steamclock [Release Management Guide](https://github.
- [1] Add log rotation functionality
- Update Log Level Presets to match specs from TechWG discussion (#83)
- Updated to Gradle 7.0; updated 3rd party libraries (#86)
- Updated readme (#88)
- InitWith method takes Config parameter (#91)
- Renamed ThrowableBlocker to FilterOut (#95)
- Simplify Sentry setup (#84)
Expand Down
283 changes: 157 additions & 126 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,36 @@
# SteamcLog Android

[Current Proposal Spec](https://docs.google.com/document/d/1GeFAMBn_ZrIP7qVLzcYlCfqDnPiCrgMa0JdrU8HRx94/edit?usp=sharing)
[Technical Documentation](https://coda.io/d/SteamcLog-Public-Documentation_dYDBWMQYscM/SteamcLog-Technical-Documentation_suPjU)

[iOS Version](https://github.com/steamclock/steamclog)
[iOS Repo](https://github.com/steamclock/steamclog)

An open source library that consolidates/formalizes the logging setup and usage across all of Steamclock's projects.

## Table of Contents
- [Development](#development)
* [Deploying new versions](#deploying-new-versions)
- [Usage](#usage)
* [Installation](#installation)
* [Initialization](#initialization)
+ [Enabling External File Logging](#enabling-external-file-logging)
+ [Setting up a Throwable/Exception "Block List"](#setting-up-a-throwable-exception--block-list-)
* [Initialization (Required)](#initialization--required-)
* [Initialization (Optional)](#initialization--optional-)
* [Enabling Sentry Reporting](#enabling-sentry-reporting)
+ [Enabling Firebase Crashlytics (No longer supported)](#enabling-firebase-crashlytics--no-longer-supported-)
+ [Enabling Firebase Analytics (No longer supported)](#enabling-firebase-analytics--no-longer-supported-)
* [Configuration](#configuration)
+ [logLevel: LogLevelPreset](#loglevel--loglevelpreset)
+ [requireRedacted: Bool](#requireredacted--bool)
* [Common methods](#common-methods)
+ [If application already has Sentry setup:](#if-application-already-has-sentry-setup-)
+ [If project does not have Sentry setup:](#if-project-does-not-have-sentry-setup-)
+ [Filtering out some Throwables from being logged to Sentry](#filtering-out-some-throwables-from-being-logged-to-sentry)
* [Common logging methods](#common-logging-methods)
+ [Basic Signatures](#basic-signatures)
+ [Error and Fatal Specific Signatures](#error-and-fatal-specific-signatures)
* [Interfaces](#interfaces)
+ [Redactable](#redactable)
+ [FilterOut](#filterout)
* [Exporting Logs](#exporting-logs)
+ [Variable Redaction](#variable-redaction)
* [Firebase](#firebase)
+ [Enabling Firebase Crashlytics (No longer supported)](#enabling-firebase-crashlytics--no-longer-supported-)
+ [Enabling Firebase Analytics (No longer supported)](#enabling-firebase-analytics--no-longer-supported-)
- [Development](#development)
* [Deploying new versions](#deploying-new-versions)

<small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with markdown-toc</a></i></small>


## Development

### Deploying new versions

These steps are for developers looking to create a new release of the Steamclog library; if this does not pertain to you, please skip down to the **Installation** section.

Currently we are hosting the library on [Jitpack](https://jitpack.io/), to deploy a new version of the library:

1. Push all changes to master
2. From within the GitHub repo, navigate to the Code panel; on the right side should be a **Releases** section
3. Click on **Releases** (which should take you [here](https://github.com/steamclock/steamclog-android/releases))
4. Make note of the latest release version name (ie. v1.1)
5. Click the **Draft a new release** button on the right
6. Set the **Tag Version**; it's best use the last release version as a guide (ie. set as v1.2)
7. Set **Release Title** to be "Steamclog <Version>"
8. Description is optional, could set changelog here if desired
9. Click the **Publish Release** button at the bottom
10. Verify on the [Jitpack page for the Steamclog project](https://jitpack.io/#steamclock/steamclog-android) that the new version is available
11. Update projects using Steamclog with the new version

## Usage

### Installation
Expand Down Expand Up @@ -77,137 +59,186 @@ Most recent version can be found [here](https://github.com/steamclock/steamclog-

4. `Steamclog` singleton should now be available

### Initialization

Steamclog can also be accessed via the `clog` typealias.
### Initialization (Required)

Out of the box, Steamclog will have support for
* Printing to the console (no setup required)
* External file logging (setup required)
* Sentry reporting (setup required)
To initialize Steamclog call `clog.initWith` in your app's custom Application class's `onCreate` method.
This function takes the following required properties:
* `isDebug` (Boolean): If application is considered to be a debug build; in most cases this is your application's `BuildConfig.DEBUG` flag. Determines the default Log Level Presets Steamclog selects for the build.
* `fileWritePath` (File): Location where the file destination will write to. This is most easily done by passing along the application's `externalCacheDir` or `cacheDir` file paths.

#### Enabling External File Logging

The `Steamclog.initWith` method can be used to enable external logging; this method only needs to be called once, and can be done in your Application object's `onCreate` method.

To enable Steamclog to write to the device, you must specify where the files should be stored, this is most easily done by passing along the application's `externalCacheDir` or `cacheDir` references.
You can specify how long one file will be used for between rotations using `fileRotationSeconds`. The default value is 600 seconds, or 10 minutes.
```
clog.initWith(BuildConfig.DEBUG, fileWritePath = externalCacheDir, fileRotationSeconds = 600)
Example:
```
* See https://developer.android.com/training/data-storage for details on the pros and cons of each.

#### Setting up a Throwable/Exception "Block List"
If you'd like to suppress a Throwable or Exception from _ever_ being logged as an error in your crash reporting system, the `throwableBlocker` interface can be overridden to allow the application to determine which Throwables should be be blocked. This can allow us to catch and redirect certain Throwables to be logged as an "App Health Analytic" instead. By default all Throwables will be logged as errors.

This can be setup at any point by implementing the `throwableBlocker` interface:
class App: Application() {
...
override fun onCreate() {
clog.initWith(BuildConfig.DEBUG, externalCacheDir)
}
```
clog.throwableBlocker = ThrowableBlocker { throwable ->
when (throwable) {
is BlockedException1 -> {
// For example, we could log this as an analytic.
true
}
is BlockedException2 -> {
// For example, we could want to do nothing and ignore this exception.
// Or maybe we want to log this as info instead.
true
}
else -> {
// The Throwable is not blocked, and will be sent as an error to the crash reporting destination.
false
}
}
```

### Enabling Sentry Reporting

To setup Sentry reporting in your project, see https://docs.sentry.io/platforms/android/
Once initialized, this will give out of the box support for printing to the console and writing to a file. Further steps are required to enable remote logging to Sentry.

You will need to create a new application on the Sentry dashboard which requires admin access. If your project required Proguard or R8 please see the above Sentry documentation as some settings may need to be put in place to properly upload the mappings accordingly.
### Initialization (Optional)

Once your main project has Sentry enabled no further work should be required for Steamclog to report to it.

#### Enabling Firebase Crashlytics (No longer supported)
The Config object has the following optional properties which may be overridden if desired. These may be set initially when calling `initWith` or updated at run time.

_Firebase Crashlytics is no longer a supported destination for crash reporting_
`Config`:
* `keepLogsForDays` (Int, default 3): Determines how long generated log files are kept for.
* `autoRotateConfig` (AutoRotateConfig, see below): Configuration for auto-rotating file behaviour.
* `requireRedacted` (Boolean, default false): Indicates if any extra objects being logged must implement the redacted interface. For apps with very sensitive data models, it is suggested to set this to true.
* `filtering` (FilteredOut, default nothing filtered): Allows application to implement the FilteredOut interface.
* `logLevel`: (LogLevelPreset, default based on `isDebug` setting): Destination logging levels; it is recommended to use the defaults set by Steamclog instead of initializing these manually. In special cases where more data is desired, update this property.

`AutoRotateConfig`:
* `fileRotationSeconds` (Long, default 600): The number of seconds before a log file is rotated; default of 600 == 10 mins.

#### Enabling Firebase Analytics (No longer supported)

_Firebase Analytics is no longer a supported for tracking analytics; tracking must be handled manually by the calling project_
Example:
```
class App: Application() {
...
override fun onCreate() {
clog.initWith(Config(
BuildConfig.DEBUG,
externalCacheDir,
keepLogsForDays = 3,
autoRotateConfig = AutoRotateConfig(fileRotationSeconds = 600L),
requireRedacted = false,
filtering = { throwable ->
when (throwable) {
is BlockedException1 -> true
is BlockedException2 -> true
else -> false
}
}
))
}
```

### Enabling Sentry Reporting

### Configuration
#### If application already has Sentry setup:
* Remove the sentry library import from your app `build.gradle`; steamclog will import this for you now.

SteamcLog has a number of configuration options
That should be it! Steamclog should now be responsible for calling all Sentry commands using the Sentry dsn values already setup on the project.

#### logLevel: LogLevelPreset
Default value is: `develop`.
There are four log level presets available, each of which has different logging outputs.
#### If project does not have Sentry setup:
If the application is **not** setup to report to Sentry yet, do the following:
1. Create a new application on the Sentry dashboard; see the `Step 1: Create the project` section on https://docs.sentry.io/product/sentry-basics/guides/integrate-frontend/create-new-project/ for full details, making sure to select Android as the platform. You do not need to worry about setting up alerts at this time. Once completed, you should be given a Sentry DSN string; hold onto this for now.
2. In your application's `AndroidManifest` file add the following line to the application object. And that should be it! Steamclog will use this dsn value when reporting to Sentry.
```
<meta-data android:name="io.sentry.dsn" android:value="<Your Sentry DSN String from step 1" />
```
| LogLevelPreset | Disk Level | System Level | Remote Level |
|-------------------|------------|--------------|--------------|
| `firehose` | verbose | verbose | none |
| `develop` | none | debug | none |
| `release` | none | none | info |
| `releaseAdvanced` | verbose | none | verbose |
3. (Optional, if your project makes use of Proguard or R8) In your app's `build.gradle` file, add the following plugin. See https://github.com/getsentry/sentry-android-gradle-plugin for the most current release version. This plugin is responsible for uploading the mappings for the build to Sentry so that we get nice, readable stack traces.
```
'io.sentry.android.gradle'
```
In most cases, you'll be able to get by using `firehose` or `develop` on debug builds, and `release` or `releaseAdvanced` for production builds.
Note that if you're using `releaseAdvanced` you must build in a way for the client to email you the disk logs.
#### Filtering out some Throwables from being logged to Sentry
See the `FilterOut` interface and `filtering` config property.
#### requireRedacted: Bool
Default value is `false`.
Require that all logged objects conform to Redacted or are all redacted by default.
### Common methods
### Common logging methods
From there, you can use `clog` anywhere in your application with the following levels. Note that availability of these logs will depend on your Configuration's `logLevel`.
See the [API Docs](https://coda.io/d/SteamcLog-Public-Documentation_dYDBWMQYscM/API-Docs_suZP0#_lu7W8) for full details
`clog.verbose` - Log all of the things! Probably only output to the console by developers, never to devices.
`clog.debug` - Info that is interesting to developers, any information that may be helpful when debugging. Should be stored to system logs for debug builds but never stored in production.
`clog.info` - Routine app operations, used to document changes in state within the application. Minimum level of log stored in device logs in production.
`clog.warn` - Developer concerns or incorrect state etc. Something’s definitely gone wrong, but there’s a path to recover
`clog.error` - Something has gone wrong, report to a remote service (like Sentry)
`clog.fatal` - Something has gone wrong and we cannot recover, so force the app to close.
* `clog.verbose` - Log all of the things! Probably only output to the console by developers, never to devices.
* `clog.debug` - Info that is interesting to developers, any information that may be helpful when debugging. Should be stored to system logs for debug builds but never stored in production.
* `clog.info` - Routine app operations, used to document changes in state within the application. Minimum level of log stored in device logs in production.
* `clog.warn` - Developer concerns or incorrect state etc. Something’s definitely gone wrong, but there’s a path to recover
* `clog.error` - Something has gone wrong, report to a remote service (like Sentry)
* `clog.fatal` - Something has gone wrong and we cannot recover, so force the app to close.
#### Basic Signatures
Each of these functions has the following 2 available signatures:
`clog.<level>(_ message: String)`
`clog.<level>(_ message: String, object: Any)`
* `clog.<level>(_ message: String)`
* `clog.<level>(_ message: String, object: Any)`
If `requireRedacted` is set to `true`, then the Any object *must* implement the Redactable interface, else all properties will be shown as `<REDACTED>`.
#### Error and Fatal Specific Signatures
Error and Fatal levels have a special signature that allows a given Throwable to be associated with the log.
`clog.<level>(_ message: String, throwable: Throwable, object: Any)`
Error and Fatal levels have a special signature that allows a given Throwable to be associated with the log.
* `clog.<level>(_ message: String, throwable: Throwable, object: Any)`
If no `Throwable` object is given for an error or fatal log, Steamclog will create a generic `NonFatalException` instance that will be used to generate crash reports on Sentry.
Please note, an error will only be logged if the Throwable is _not_ in the blocked via the `ThrowableBlocker` interface implementation.
Please note, an error will only be logged if the Throwable is _not_ in the blocked via the `FilterOut` interface implementation.
### Exporting Logs
### Interfaces
If logging to a file has been enabled, then files, you can get the log file contents using `clog.getLogFileContents(): String?`

#### Variable Redaction

`Redacted` is a protocol that can be conformed to by a struct or class for marking particular fields as safe for logging. By default, a class implementing the `Redactable` will have all fields marked as redacted, and you can define logging-safe fields using the `safeProperties` field.

Example:
#### Redactable
Classes that wish to be flagged as Redactable can be implementated as follows:
```kotlin
import com.steamclock.steamclog.*
data class User(val name: String, val email: String, val bankingSecret: String) : Redactable {
override val safeProperties: Set<String> = HashSet<String>(setOf("name"))
override val safeProperties = HashSet<String>(setOf("name"))
}
```

In this case, when a `User` object is logged by Steamclog, it will log something like the following:
In this case, when a `User` object is logged by Steamclog like:
```
clog.info("Testing Redactable Class", User("shayla", "me@email.com", "123456"))
```
And the log will output:
`Testing Redactable Class : User(bankingSecret=<redacted>, email=<redacted>, name=shayla)`
The logged output would appear as:
```
Testing Redactable Class : User(bankingSecret=<redacted>, email=<redacted>, name=shayla)
```
The `name` value may be logged, but the `email` and `bankingSecret` values will be redacted.

#### FilterOut
A `FilterOut` implementation may look like:
```
var filtering = FilterOut { throwable ->
when (throwable) {
is BlockedException1 -> true
is BlockedException2 -> true
else -> false
}
```
or be implementated on a given class:
```
class App : Application(), FilterOut {
...
override fun shouldBlock(throwable: Throwable): Boolean {
return when (throwable) {
is BlockedException1 -> true
is BlockedException2 -> true
else -> false
}
}
}
```

### Exporting Disk Logs

If logging to a file has been enabled, then files, you can get the log file contents using `clog.getLogFileContents(): String?`

### Firebase

#### Enabling Firebase Crashlytics (No longer supported)

_Firebase Crashlytics is no longer a supported destination for crash reporting_

#### Enabling Firebase Analytics (No longer supported)

_Firebase Analytics is no longer a supported for tracking analytics; tracking must be handled manually by the calling project_

## Development

### Deploying new versions

These steps are for developers looking to create a new release of the Steamclog library; if this does not pertain to you, please skip down to the **Installation** section.

Currently we are hosting the library on [Jitpack](https://jitpack.io/), to deploy a new version of the library:

1. Push all changes to master
2. From within the GitHub repo, navigate to the Code panel; on the right side should be a **Releases** section
3. Click on **Releases** (which should take you [here](https://github.com/steamclock/steamclog-android/releases))
4. Make note of the latest release version name (ie. v1.1)
5. Click the **Draft a new release** button on the right
6. Set the **Tag Version**; it's best use the last release version as a guide (ie. set as v1.2)
7. Set **Release Title** to be "Steamclog <Version>"
8. Description is optional, could set changelog here if desired
9. Click the **Publish Release** button at the bottom
10. Verify on the [Jitpack page for the Steamclog project](https://jitpack.io/#steamclock/steamclog-android) that the new version is available
11. Update projects using Steamclog with the new version

0 comments on commit eff8b48

Please sign in to comment.