Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions firrtl/src/main/scala/logger/Logger.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ private class LoggerState {
val classToLevelCache = new scala.collection.mutable.HashMap[String, LogLevel.Value]
var logClassNames = false
var stream: PrintStream = Console.out
var errorStream: PrintStream = Console.err
var fromInvoke: Boolean = false // this is used to not have invokes re-create run-state
var stringBufferOption: Option[Logger.OutputCaptor] = None

Expand All @@ -79,6 +80,7 @@ private class LoggerState {
newState.globalLevel = this.globalLevel
newState.classLevels ++= this.classLevels
newState.stream = this.stream
newState.errorStream = this.errorStream
newState.logClassNames = this.logClassNames
newState
}
Expand Down Expand Up @@ -211,10 +213,15 @@ object Logger {
*/
private def showMessage(level: LogLevel.Value, className: String, message: => String): Unit = {
def logIt(): Unit = {
// Use errorStream for Error and Warn levels, stream for others
val stream = level match {
case LogLevel.Error | LogLevel.Warn => state.errorStream
case _ => state.stream
Comment on lines +218 to +219
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say put everything into errorStream. This would level Info and Debug going to stdout right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah currently I'm having it send Warn and Error to stderr and the others to stdout, your point is a good one though...

}
if (state.logClassNames) {
state.stream.println(s"[$level:$className] $message")
stream.println(s"[$level:$className] $message")
} else {
state.stream.println(message)
stream.println(message)
}
}
testPackageNameMatch(className, level) match {
Expand Down Expand Up @@ -243,6 +250,7 @@ object Logger {
state.logClassNames = false
state.globalLevel = LogLevel.Error
state.stream = System.out
state.errorStream = Console.err
}

/**
Expand Down Expand Up @@ -302,24 +310,53 @@ object Logger {
/**
* Set the logging destination to a file name
* @param fileName destination name
* @deprecated Use setStandardOutput and setErrorOutput instead. This method sets both standard and error streams to the same file.
*/
@deprecated(
"Use setStandardOutput and setErrorOutput instead. This method sets both standard and error streams to the same file.",
"Chisel 7.10.0"
)
def setOutput(fileName: String): Unit = {
state.stream = new PrintStream(new FileOutputStream(new File(fileName)))
state.errorStream = new PrintStream(new FileOutputStream(new File(fileName)))
}

/**
* Set the logging destination to a print stream
* @param stream destination stream
* @deprecated Use setStandardOutput and setErrorOutput instead. This method sets both standard and error streams to the same stream.
*/
@deprecated(
"Use setStandardOutput and setErrorOutput instead. This method sets both standard and error streams to the same stream.",
"Chisel 7.10.0"
)
def setOutput(stream: PrintStream): Unit = {
state.stream = stream
state.errorStream = stream
}

/**
* Set the standard logging destination to a print stream (for Info, Debug, Trace levels)
* @param stream destination stream for standard output
*/
def setStandardOutput(stream: PrintStream): Unit = {
state.stream = stream
}

/**
* Set the error logging destination to a print stream (for Error and Warn levels)
* @param stream destination stream for errors and warnings
*/
def setErrorOutput(stream: PrintStream): Unit = {
state.errorStream = stream
}

/**
* Sets the logging destination to Console.out
* Sets the logging destination to Console.out and Console.err
*/
def setConsole(): Unit = {
state.stream = Console.out
state.errorStream = Console.err
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class UnrecognizedAnnotationSpec extends FirrtlFlatSpec {
// Default log level is error, which the JSON parsing uses here
Logger.makeScope(Seq()) {
val captor = new OutputCaptor
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)

val parsingError = intercept[UnrecogizedAnnotationsException] {
JsonProtocol.deserialize(
Expand Down
45 changes: 30 additions & 15 deletions firrtl/src/test/scala/loggertests/LoggerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
"setting level to None will result in warn messages" in {
Logger.makeScope() {
val captor = new OutputCaptor
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)
Logger.setLevel(LogLevel.None)

val r1 = new Logger1
Expand All @@ -62,7 +63,8 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
"only warn and error shows up by default" in {
Logger.makeScope() {
val captor = new OutputCaptor
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)

val r1 = new Logger1
r1.run()
Expand All @@ -79,7 +81,8 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
"setting level to warn will result in error and warn messages" in {
Logger.makeScope() {
val captor = new OutputCaptor
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)
Logger.setLevel(LogLevel.Warn)

val r1 = new Logger1
Expand All @@ -95,7 +98,8 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
"setting level to info will result in error, info, and warn messages" in {
Logger.makeScope() {
val captor = new OutputCaptor
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)
Logger.setLevel(LogLevel.Info)

val r1 = new Logger1
Expand All @@ -111,10 +115,12 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
"setting level to debug will result in error, info, debug, and warn messages" in {
Logger.makeScope() {
val captor = new OutputCaptor
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)

Logger.setLevel(LogLevel.Error)
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)
Logger.setLevel(LogLevel.Debug)

val r1 = new Logger1
Expand All @@ -131,10 +137,12 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
"setting level to trace will result in error, info, debug, trace, and warn messages" in {
Logger.makeScope() {
val captor = new OutputCaptor
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)

Logger.setLevel(LogLevel.Error)
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)
Logger.setLevel(LogLevel.Trace)

val r1 = new Logger1
Expand All @@ -154,7 +162,8 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
"capture logging from LogsInfo2" in {
Logger.makeScope() {
val captor = new OutputCaptor
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)

Logger.setLevel("loggertests.LogsInfo2", LogLevel.Info)

Expand All @@ -172,7 +181,8 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
"capture logging from LogsInfo2 using class" in {
Logger.makeScope() {
val captor = new OutputCaptor
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)

Logger.setLevel(classOf[LogsInfo2], LogLevel.Info)

Expand All @@ -190,7 +200,8 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
"capture logging from LogsInfo3" in {
Logger.makeScope() {
val captor = new OutputCaptor
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)

Logger.setLevel("loggertests.LogsInfo3", LogLevel.Info)

Expand All @@ -210,7 +221,8 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
"both log because of package, also showing re-run after change works" in {
Logger.makeScope() {
val captor = new OutputCaptor
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)

Logger.setLevel(LogLevel.Error)
Logger.setLevel("loggertests", LogLevel.Error)
Expand Down Expand Up @@ -240,7 +252,8 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
"check for false positives" in {
Logger.makeScope() {
val captor = new OutputCaptor
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)

Logger.setLevel("bad-loggertests", LogLevel.Info)

Expand All @@ -258,7 +271,8 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
"show that class specific level supercedes global level" in {
Logger.makeScope() {
val captor = new OutputCaptor
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)

Logger.setLevel(LogLevel.Info)
Logger.setLevel("loggertests.LogsInfo2", LogLevel.Error)
Expand All @@ -277,7 +291,8 @@ class LoggerSpec extends AnyFreeSpec with Matchers with OneInstancePerTest with
"Show that printstream remains across makeScopes" in {
Logger.makeScope() {
val captor = new Logger.OutputCaptor
Logger.setOutput(captor.printStream)
Logger.setStandardOutput(captor.printStream)
Logger.setErrorOutput(captor.printStream)

logger.error("message 1")
Logger.makeScope() {
Expand Down
2 changes: 1 addition & 1 deletion lit/tests/ErrorCarat.sc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: JDK_JAVA_OPTIONS='-Dchisel.project.root=' not scala-cli --server=false --java-home=%JAVAHOME --extra-jars=%RUNCLASSPATH --scala-version=%SCALAVERSION --scala-option="-Xplugin:%SCALAPLUGINJARS" %s | FileCheck %s
// RUN: JDK_JAVA_OPTIONS='-Dchisel.project.root=' not scala-cli --server=false --java-home=%JAVAHOME --extra-jars=%RUNCLASSPATH --scala-version=%SCALAVERSION --scala-option="-Xplugin:%SCALAPLUGINJARS" %s 2>&1 | FileCheck %s
// SPDX-License-Identifier: Apache-2.0

import chisel3._
Expand Down
8 changes: 4 additions & 4 deletions src/test/scala-2/circtTests/stage/ChiselStageSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ class ChiselStageSpec extends AnyFunSpec with Matchers with chiselTests.LogUtils
}
}

val lines = stdout.split("\n")
val lines = stderr.split("\n")
// Fuzzy includes aren't ideal but there is ANSI color in these strings that is hard to match
lines(0) should include(
"src/test/scala-2/circtTests/stage/ChiselStageSpec.scala 122:9: Negative shift amounts are illegal (got -1)"
Expand All @@ -635,7 +635,7 @@ class ChiselStageSpec extends AnyFunSpec with Matchers with chiselTests.LogUtils
}
}

val lines = stdout.split("\n")
val lines = stderr.split("\n")
// Fuzzy includes aren't ideal but there is ANSI color in these strings that is hard to match
lines.size should equal(2)
lines(0) should include(
Expand All @@ -662,7 +662,7 @@ class ChiselStageSpec extends AnyFunSpec with Matchers with chiselTests.LogUtils
}
}

val lines = stdout.split("\n")
val lines = stderr.split("\n")
// Fuzzy includes aren't ideal but there is ANSI color in these strings that is hard to match
lines(0) should include("Foo 3:10: Negative shift amounts are illegal (got -1)")
lines(1) should include("I am the file in sourceroot1")
Expand All @@ -687,7 +687,7 @@ class ChiselStageSpec extends AnyFunSpec with Matchers with chiselTests.LogUtils
}
}

val lines = stdout.split("\n")
val lines = stderr.split("\n")
// Fuzzy includes aren't ideal but there is ANSI color in these strings that is hard to match
lines(0) should include("Foo 3:10: Negative shift amounts are illegal (got -1)")
lines(1) should include("I am the file in sourceroot2")
Expand Down
3 changes: 2 additions & 1 deletion src/test/scala/chiselTests/LogUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ trait LogUtils {
val baos = new ByteArrayOutputStream()
val stream = new PrintStream(baos, true, "utf-8")
val ret = Logger.makeScope(LogLevelAnnotation(level) :: Nil) {
Logger.setOutput(stream)
Logger.setStandardOutput(stream)
Logger.setErrorOutput(stream)
thunk
}
(baos.toString, ret)
Expand Down
Loading