Skip to content

Commit

Permalink
Merge "HostStubGen: Write verbose/debug log to a file" into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Makoto Onuki authored and Android (Google) Code Review committed Nov 29, 2023
2 parents 2287eb6 + 623cffb commit 6f6392a
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 102 deletions.
4 changes: 4 additions & 0 deletions Ravenwood.bp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ java_genrule {
cmd: "$(location hoststubgen) " +
"@$(location ravenwood/ravenwood-standard-options.txt) " +

"--debug-log $(location hoststubgen_framework-minus-apex.log) " +

"--out-impl-jar $(location ravenwood.jar) " +

"--gen-keep-all-file $(location hoststubgen_keep_all.txt) " +
Expand All @@ -52,6 +54,8 @@ java_genrule {
// Following files are created just as FYI.
"hoststubgen_keep_all.txt",
"hoststubgen_dump.txt",

"hoststubgen_framework-minus-apex.log",
],
visibility: ["//visibility:private"],
}
Expand Down
2 changes: 1 addition & 1 deletion ravenwood/ravenwood-standard-options.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# File containing standard options to HostStubGen for Ravenwood

--debug
# --debug # To enable debug log on consone

# Keep all classes / methods / fields, but make the methods throw.
--default-throw
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,6 @@ EXTRA_ARGS="--in-jar abc" run_hoststubgen_for_failure "Duplicate arg" \
"Duplicate or conflicting argument found: --in-jar" \
""

EXTRA_ARGS="--quiet" run_hoststubgen_for_failure "Conflicting arg" \
"Duplicate or conflicting argument found: --quiet" \
""


echo "All tests passed"
exit 0
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ class HostStubGen(val options: HostStubGenOptions) {
errors: HostStubGenErrors,
) {
log.i("Converting %s into [stub: %s, impl: %s] ...", inJar, outStubJar, outImplJar)
log.i("Checker is %s", if (enableChecker) "enabled" else "disabled")
log.i("ASM CheckClassAdapter is %s", if (enableChecker) "enabled" else "disabled")

val start = System.currentTimeMillis()

Expand All @@ -264,7 +264,7 @@ class HostStubGen(val options: HostStubGenOptions) {
}
}
val end = System.currentTimeMillis()
log.v("Done transforming the jar in %.1f second(s).", (end - start) / 1000.0)
log.i("Done transforming the jar in %.1f second(s).", (end - start) / 1000.0)
}

private fun <T> maybeWithZipOutputStream(filename: String?, block: (ZipOutputStream?) -> T): T {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
*/
package com.android.hoststubgen

import java.io.OutputStream
import java.io.PrintStream
import java.io.BufferedOutputStream
import java.io.FileOutputStream
import java.io.PrintWriter
import java.io.Writer

val log: HostStubGenLogger = HostStubGenLogger()
val log: HostStubGenLogger = HostStubGenLogger().setConsoleLogLevel(LogLevel.Info)

/** Logging level */
enum class LogLevel {
Expand All @@ -30,15 +32,13 @@ enum class LogLevel {
Debug,
}

/** Simple logging class. */
class HostStubGenLogger(
private var out: PrintStream = System.out!!,
var level: LogLevel = LogLevel.Info,
) {
companion object {
private val sNullPrintStream: PrintStream = PrintStream(OutputStream.nullOutputStream())
}

/**
* Simple logging class.
*
* By default, it has no printers set. Use [setConsoleLogLevel] or [addFilePrinter] to actually
* write log.
*/
class HostStubGenLogger {
private var indentLevel: Int = 0
get() = field
set(value) {
Expand All @@ -47,6 +47,56 @@ class HostStubGenLogger(
}
private var indent: String = ""

private val printers: MutableList<LogPrinter> = mutableListOf()

private var consolePrinter: LogPrinter? = null

private var maxLogLevel = LogLevel.None

private fun updateMaxLogLevel() {
maxLogLevel = LogLevel.None

printers.forEach {
if (maxLogLevel < it.logLevel) {
maxLogLevel = it.logLevel
}
}
}

private fun addPrinter(printer: LogPrinter) {
printers.add(printer)
updateMaxLogLevel()
}

private fun removePrinter(printer: LogPrinter) {
printers.remove(printer)
updateMaxLogLevel()
}

fun setConsoleLogLevel(level: LogLevel): HostStubGenLogger {
// If there's already a console log printer set, remove it, and then add a new one
consolePrinter?.let {
removePrinter(it)
}
val cp = StreamPrinter(level, PrintWriter(System.out))
addPrinter(cp)
consolePrinter = cp

return this
}

fun addFilePrinter(level: LogLevel, logFilename: String): HostStubGenLogger {
addPrinter(StreamPrinter(level, PrintWriter(BufferedOutputStream(
FileOutputStream(logFilename)))))

return this
}

/** Flush all the printers */
fun flush() {
printers.forEach { it.flush() }
}

fun indent() {
indentLevel++
}
Expand All @@ -68,92 +118,71 @@ class HostStubGenLogger(
}

fun isEnabled(level: LogLevel): Boolean {
return level.ordinal <= this.level.ordinal
return level.ordinal <= maxLogLevel.ordinal
}

private fun println(message: String) {
out.print(indent)
out.println(message)
private fun println(level: LogLevel, message: String) {
printers.forEach {
if (it.logLevel.ordinal >= level.ordinal) {
it.println(level, indent, message)
}
}
}

private fun println(level: LogLevel, format: String, vararg args: Any?) {
if (isEnabled(level)) {
println(level, String.format(format, *args))
}
}

/** Log an error. */
fun e(message: String) {
if (level.ordinal < LogLevel.Error.ordinal) {
return
}
println(message)
println(LogLevel.Error, message)
}

/** Log an error. */
fun e(format: String, vararg args: Any?) {
if (level.ordinal < LogLevel.Error.ordinal) {
return
}
e(String.format(format, *args))
println(LogLevel.Error, format, *args)
}

/** Log a warning. */
fun w(message: String) {
if (level.ordinal < LogLevel.Warn.ordinal) {
return
}
println(message)
println(LogLevel.Warn, message)
}

/** Log a warning. */
fun w(format: String, vararg args: Any?) {
if (level.ordinal < LogLevel.Warn.ordinal) {
return
}
w(String.format(format, *args))
println(LogLevel.Warn, format, *args)
}

/** Log an info message. */
fun i(message: String) {
if (level.ordinal < LogLevel.Info.ordinal) {
return
}
println(message)
println(LogLevel.Info, message)
}

/** Log a debug message. */
/** Log an info message. */
fun i(format: String, vararg args: Any?) {
if (level.ordinal < LogLevel.Warn.ordinal) {
return
}
i(String.format(format, *args))
println(LogLevel.Info, format, *args)
}

/** Log a verbose message. */
fun v(message: String) {
if (level.ordinal < LogLevel.Verbose.ordinal) {
return
}
println(message)
println(LogLevel.Verbose, message)
}

/** Log a verbose message. */
fun v(format: String, vararg args: Any?) {
if (level.ordinal < LogLevel.Verbose.ordinal) {
return
}
v(String.format(format, *args))
println(LogLevel.Verbose, format, *args)
}

/** Log a debug message. */
fun d(message: String) {
if (level.ordinal < LogLevel.Debug.ordinal) {
return
}
println(message)
println(LogLevel.Debug, message)
}

/** Log a debug message. */
fun d(format: String, vararg args: Any?) {
if (level.ordinal < LogLevel.Warn.ordinal) {
return
}
d(String.format(format, *args))
println(LogLevel.Debug, format, *args)
}

inline fun forVerbose(block: () -> Unit) {
Expand All @@ -168,31 +197,65 @@ class HostStubGenLogger(
}
}

/** Return a stream for error. */
fun getErrorPrintStream(): PrintStream {
if (level.ordinal < LogLevel.Error.ordinal) {
return sNullPrintStream
/** Return a Writer for a given log level. */
fun getWriter(level: LogLevel): Writer {
return MultiplexingWriter(level)
}

private inner class MultiplexingWriter(val level: LogLevel) : Writer() {
private inline fun forPrinters(callback: (LogPrinter) -> Unit) {
printers.forEach {
if (it.logLevel.ordinal >= level.ordinal) {
callback(it)
}
}
}

// TODO Apply indent
return PrintStream(out)
}
override fun close() {
flush()
}

/** Return a stream for verbose messages. */
fun getVerbosePrintStream(): PrintStream {
if (level.ordinal < LogLevel.Verbose.ordinal) {
return sNullPrintStream
override fun flush() {
forPrinters {
it.flush()
}
}
// TODO Apply indent
return PrintStream(out)
}

/** Return a stream for debug messages. */
fun getInfoPrintStream(): PrintStream {
if (level.ordinal < LogLevel.Info.ordinal) {
return sNullPrintStream
override fun write(cbuf: CharArray, off: Int, len: Int) {
// TODO Apply indent
forPrinters {
it.write(cbuf, off, len)
}
}
// TODO Apply indent
return PrintStream(out)
}
}
}

private interface LogPrinter {
val logLevel: LogLevel

fun println(logLevel: LogLevel, indent: String, message: String)

// TODO: This should be removed once MultiplexingWriter starts applying indent, at which point
// println() should be used instead.
fun write(cbuf: CharArray, off: Int, len: Int)

fun flush()
}

private class StreamPrinter(
override val logLevel: LogLevel,
val out: PrintWriter,
) : LogPrinter {
override fun println(logLevel: LogLevel, indent: String, message: String) {
out.print(indent)
out.println(message)
}

override fun write(cbuf: CharArray, off: Int, len: Int) {
out.write(cbuf, off, len)
}

override fun flush() {
out.flush()
}
}
Loading

0 comments on commit 6f6392a

Please sign in to comment.