Skip to content

Commit

Permalink
avito.logging.verbose property (#923)
Browse files Browse the repository at this point in the history
* new avito.logging.verbose property to override local console output log levels for out plugins
* use println (quiet level in gradle)
* add stacktrace print control, extract VerboseDestination
  • Loading branch information
dsvoronin committed Apr 12, 2021
1 parent 38602a3 commit 25d7592
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 16 deletions.
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ instrumentation=Ui
stacktrace?=
project=-p subprojects

# see Logging.md#Verbose-mode
verbose?=

docker_command?=

ifeq ($(docker),true)
Expand Down Expand Up @@ -62,6 +65,10 @@ ifdef infra
params +=-PinfraVersion=$(infra)
endif

ifdef verbose
params +=-Pavito.logging.verbosity=$(verbose)
endif

params +=-PtestBuildType=$(test_build_type)
params +=-Pci=$(ci)
params +=$(log_level)
Expand Down
37 changes: 34 additions & 3 deletions docs/content/contributing/Logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
To obtain a logger for Gradle use `GradleLoggerFactory` methods:

```kotlin
abstract class MyTask: DefaultTask() {
abstract class MyTask : DefaultTask() {

@TaskAction
fun doWork() {
val loggerFactory: LoggerFactory = GradleLoggerFactory.fromTask(this)
}
}
```

## Logging in Android
## Logging in Android

To obtain logger for android create `AndroidLoggerFactory`

Expand Down Expand Up @@ -46,3 +46,34 @@ val logger = loggerFactory.create("MyCustomTag")
`StubLoggerFactory` and `StubLogger` can be used in tests

`StubLogger` will write to stdout only during test runs from IDE

## Verbose mode

Use gradle property `avito.logging.verbosity` to override gradle logging level and send avito logs to stdout (e.g. with
gradle's `quiet` level.)

Value defines which levels to override.

For example: `-Pavito.logging.verbosity=INFO` makes `INFO` and higher(`WARNING`) levels act like level quiet

`CRITICAL`, which is mapped to gradle's `error` level is visible already on quiet level

Possible values are in `DEBUG`, `INFO`, `WARNING`, `CRITICAL` (see `com.avito.logger.LogLevel`)

Default is not defined

### Stacktrace

Add gradle's `--stacktrace` to also print stacktraces in verbose mode if available

### Why is it needed?

Gradle use lifecycle level by default, but to see info or debug level you have to set it for whole gradle run
via `--info` or `--debug`, which made console output unreadable and build slow.

There is an issue for
that: [gradle/#1010 Ability to set log level for specific task](https://github.com/gradle/gradle/issues/1010)

With verbose flag you are able to tune log level for avito plugins separately.

It only affects console output, and not affecting custom loggers like elastic.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.avito.logger.destination

import com.avito.logger.LogLevel
import com.avito.logger.LoggingDestination

data class VerboseMode(
val verbosity: LogLevel,
val printStackTrace: Boolean
)

/**
* See Logging.md#Verbose-mode
*/
class VerboseDestination(private val verboseMode: VerboseMode) : LoggingDestination {

private val verbosity = verboseMode.verbosity

override fun write(level: LogLevel, message: String, throwable: Throwable?) {
when (level) {
LogLevel.DEBUG -> if (verbosity == LogLevel.DEBUG) {
print(message, throwable)
}
LogLevel.INFO -> if (verbosity == LogLevel.DEBUG || verbosity == LogLevel.INFO) {
print(message, throwable)
}
LogLevel.WARNING -> if (verbosity == LogLevel.DEBUG
|| verbosity == LogLevel.INFO
|| verbosity == LogLevel.WARNING
) {
print(message, throwable)
}
LogLevel.CRITICAL -> print(message, throwable)
}
}

private fun print(message: String, throwable: Throwable?) {
println(message)
if (verboseMode.printStackTrace) {
throwable?.printStackTrace()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import com.avito.android.elastic.ElasticConfig
import com.avito.android.sentry.SentryConfig
import com.avito.android.sentry.sentryConfig
import com.avito.logger.destination.Slf4jDestination
import com.avito.logger.destination.VerboseDestination
import com.avito.logger.destination.VerboseMode
import com.avito.logger.formatter.AppendMetadataFormatter
import com.avito.logger.handler.CombinedHandler
import com.avito.logger.handler.DefaultLoggingHandler
Expand All @@ -12,15 +14,18 @@ import com.avito.utils.gradle.buildEnvironment
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.logging.configuration.ShowStacktrace
import java.io.Serializable
import java.util.Locale

class GradleLoggerFactory(
private val isCiRun: Boolean,
private val sentryConfig: SentryConfig,
private val elasticConfig: ElasticConfig,
private val projectPath: String,
private val pluginName: String? = null,
private val taskName: String? = null
private val taskName: String? = null,
private val verboseMode: VerboseMode?,
) : LoggerFactory, Serializable {

override fun create(tag: String): Logger = provideLogger(
Expand All @@ -32,31 +37,40 @@ class GradleLoggerFactory(
pluginName = pluginName,
projectPath = projectPath,
taskName = taskName
)
),
verboseMode = verboseMode
)

private fun provideLogger(
isCiRun: Boolean,
sentryConfig: SentryConfig,
elasticConfig: ElasticConfig,
metadata: LoggerMetadata
metadata: LoggerMetadata,
verboseMode: VerboseMode?
): Logger = if (isCiRun) {
createCiLogger(sentryConfig, elasticConfig, metadata)
createCiLogger(sentryConfig, elasticConfig, metadata, verboseMode)
} else {
createLocalBuildLogger(metadata)
createLocalBuildLogger(metadata, verboseMode)
}

private fun createCiLogger(
sentryConfig: SentryConfig,
elasticConfig: ElasticConfig,
metadata: LoggerMetadata
metadata: LoggerMetadata,
verboseMode: VerboseMode?
): Logger {

val defaultHandler = when (elasticConfig) {
is ElasticConfig.Disabled ->
DefaultLoggingHandler(
destination = Slf4jDestination(metadata.tag)
)
is ElasticConfig.Disabled -> {

val destination: LoggingDestination = if (verboseMode != null) {
VerboseDestination(verboseMode)
} else {
Slf4jDestination(metadata.tag)
}

DefaultLoggingHandler(destination = destination)
}
is ElasticConfig.Enabled ->
DefaultLoggingHandler(
destination = ElasticDestinationFactory.create(elasticConfig, metadata)
Expand All @@ -82,11 +96,20 @@ class GradleLoggerFactory(
)
}

private fun createLocalBuildLogger(metadata: LoggerMetadata): Logger {
private fun createLocalBuildLogger(
metadata: LoggerMetadata,
verboseMode: VerboseMode?
): Logger {

val destination: LoggingDestination = if (verboseMode != null) {
VerboseDestination(verboseMode)
} else {
Slf4jDestination(metadata.tag)
}

val gradleLoggerHandler = DefaultLoggingHandler(
formatter = AppendMetadataFormatter(metadata),
destination = Slf4jDestination(metadata.tag)
destination = destination
)

return DefaultLogger(
Expand Down Expand Up @@ -127,9 +150,33 @@ class GradleLoggerFactory(
elasticConfig = ElasticConfigFactory.config(project),
projectPath = project.path,
pluginName = pluginName,
taskName = taskName
taskName = taskName,
verboseMode = getVerbosity(project)?.let { VerboseMode(it, doPrintStackTrace(project)) }
)

@Suppress("UnstableApiUsage")
private fun getVerbosity(project: Project): LogLevel? {
return project.providers
.gradleProperty("avito.logging.verbosity")
.forUseAtConfigurationTime()
.map { value ->
try {
LogLevel.valueOf(value.toUpperCase(Locale.getDefault()))
} catch (e: Throwable) {
throw IllegalArgumentException(
"`avito.logging.verbosity` should be one of: " +
"${LogLevel.values().map { it.name }} but was $value"
)
}
}
.orNull
}

private fun doPrintStackTrace(project: Project): Boolean {
val showStacktrace = project.gradle.startParameter.showStacktrace
return showStacktrace == ShowStacktrace.ALWAYS || showStacktrace == ShowStacktrace.ALWAYS_FULL
}

private fun Project.isCiRun(): Boolean =
project.buildEnvironment is BuildEnvironment.CI && !project.buildEnvironment.inGradleTestKit
}
Expand Down

0 comments on commit 25d7592

Please sign in to comment.