All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.persist.logging.StdOutAppender.scala Maven / Gradle / Ivy

The newest version!
package com.persist.logging

import akka.actor.{ActorSystem, ActorContext, ActorRefFactory}
import com.persist.JsonOps._
import scala.concurrent.Future

/**
 * Companion object for the StdOutAppender class.
 */
object StdOutAppender extends LogAppenderBuilder {
  /**
   * A constructor for the StdOutAppender class.
   * @param factory an Akka factory.
   * @param stdHeaders the headers that are fixes for this service.
   * @return the stdout appender.
   */
  def apply(factory: ActorRefFactory, stdHeaders: Map[String, RichMsg]) = new StdOutAppender(factory, stdHeaders)
}

/**
 * A log appender that write common log messages to stdout.
 * @param factory an Akka factory.
 * @param stdHeaders the headers that are fixes for this service.
 */
class StdOutAppender(factory: ActorRefFactory, stdHeaders: Map[String, RichMsg]) extends LogAppender {
  private[this] val system = factory match {
    case context: ActorContext => context.system
    case s: ActorSystem => s
  }
  private[this] val config = system.settings.config.getConfig("com.persist.logging.appenders.stdout")
  private[this] val fullHeaders = config.getBoolean("fullHeaders")
  private[this] val color = config.getBoolean("color")
  private[this] val width = config.getInt("width")
  private[this] val summary = config.getBoolean("summary")
  private[this] val pretty = config.getBoolean("pretty")
  private[this] var categories = Map.empty[String, Int]
  private[this] var levels = Map.empty[String, Int]
  private[this] var kinds = Map.empty[String, Int]

  /**
   * Writes a log message to stdout.
   * @param baseMsg the message to be logged.
   * @param category  the kinds of log (for example, "common").
   */
  def append(baseMsg: Map[String, RichMsg], category: String): Unit = {
    if (category == "common") {
      val level = jgetString(baseMsg, "@severity")
      if (summary) {
        val cnt = levels.get(level).getOrElse(0) + 1
        levels += (level -> cnt)
        val kind = jgetString(baseMsg,"kind")
        if (kind != "") {
          val cnt = kinds.get(kind).getOrElse(0) + 1
          kinds += (kind -> cnt)
        }
      }
      val msg = if (fullHeaders) stdHeaders ++ baseMsg else baseMsg
      val txt = if (pretty)
        Pretty(msg - "@category", safe = true, width = width)
      else
        Compact(msg - "@category", safe = true)

      val colorTxt = if (color) {
        level match {
          case "FATAL" | "ERROR" =>
            s"${Console.RED}$txt${Console.RESET}"
          case "WARN" =>
            s"${Console.YELLOW}$txt${Console.RESET}"
          case _ => txt
        }
      } else {
        txt
      }
      println(colorTxt)
    } else if (summary) {
      val cnt = categories.get(category).getOrElse(0) + 1
      categories += (category -> cnt)
    }
  }
  /**
    * Called just before the logger shuts down.
    * @return a future that is completed when finished.
    */
  def finish(): Future[Unit] = {
    Future.successful(())
  }

  /**
   * Closes the stdout appender.
   * @return a future that is completed when the close is complete.
   */
  def stop(): Future[Unit] = {
    if (summary) {
      val cats = if (categories.size == 0) emptyJsonObject else JsonObject("alts" -> categories)
      val levs = if (levels.size == 0) emptyJsonObject else JsonObject("levels" -> levels)
      val knds = if (kinds.size == 0) emptyJsonObject else JsonObject("kinds" -> kinds)
      val txt = Pretty(levs ++ cats ++ knds, width = width)
      val colorTxt = if (color) {
        s"${Console.BLUE}$txt${Console.RESET}"
      } else {
        txt
      }
      println(colorTxt)
    }
    Future.successful(())
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy