<commit_before>package specs

import java.util.concurrent.ConcurrentLinkedQueue

import org.scalatest.{AsyncWordSpec, Matchers}
import scribe.Logger
import scribe.format._
import scribe.writer.Writer

import scala.concurrent.Future
import scala.collection.JavaConverters._
import perfolation._

class AsynchronousLoggingSpec extends AsyncWordSpec with Matchers {
  "Asynchronous Logging" should {
    val queue = new ConcurrentLinkedQueue[String]
    val logger = Logger.empty.orphan().withHandler(
      formatter = AsynchronousLoggingSpec.format,
      writer = new Writer {
        override def write(output: String): Unit = queue.add(output)
      }
    )

    "log 10000 records in the proper order" in {
      val Regex = """(\d+) - (.+)""".r

      Future.sequence("abcdefghij".map { char =>
        Future {
          (0 until 1000).foreach { index =>
            logger.info(p"$char:$index")
          }
        }
      }).map { _ =>
        var previous = 0L
        queue.iterator().asScala.foreach {
          case Regex(ts, message) => {
            val timeStamp = ts.toLong
            timeStamp should be >= previous
            previous = timeStamp
          }
        }
        queue.size() should be(10000)
      }
    }
  }
}

object AsynchronousLoggingSpec {
  val format = formatter"$timeStamp - $message"
}<commit_msg>Added asynchronous logging testing of file logging<commit_after>package specs

import java.io.File
import java.util.concurrent.ConcurrentLinkedQueue

import org.scalatest.{AsyncWordSpec, Matchers}
import scribe.Logger
import scribe.format._
import scribe.writer.{FileWriter, Writer}

import scala.concurrent.Future
import scala.collection.JavaConverters._
import perfolation._

import scala.io.Source

class AsynchronousLoggingSpec extends AsyncWordSpec with Matchers {
  private val Regex = """(\d+) - (.+)""".r
  private val threads = "abcdefghijklmnopqrstuvwxyz"
  private val iterations = 10000
  private val total = threads.length * iterations

  "Asynchronous Logging" should {
    s"log $total records in the proper order with simple logging" in {
      val queue = new ConcurrentLinkedQueue[String]
      val logger = Logger.empty.orphan().withHandler(
        formatter = AsynchronousLoggingSpec.format,
        writer = new Writer {
          override def write(output: String): Unit = queue.add(output.trim)
        }
      )

      Future.sequence(threads.map { char =>
        Future {
          (0 until iterations).foreach { index =>
            logger.info(p"$char:$index")
          }
        }
      }).map { _ =>
        var previous = 0L
        queue.iterator().asScala.foreach {
          case Regex(ts, message) => {
            val timeStamp = ts.toLong
            timeStamp should be >= previous
            previous = timeStamp
          }
        }
        queue.size() should be(total)
      }
    }
    s"log $total records in the proper order with file logging" in {
      val file = new File("logs/app.log")
      file.delete()

      val fileWriter = FileWriter.single(nio = true)
      val logger = Logger.empty.orphan().withHandler(
        formatter = AsynchronousLoggingSpec.format,
        writer = fileWriter
      )

      Future.sequence(threads.map { char =>
        Future {
          (0 until iterations).foreach { index =>
            logger.info(p"$char:$index")
          }
        }
      }).map { _ =>
        var previous = 0L
        fileWriter.flush()
        fileWriter.dispose()
        val lines = Source.fromFile(file).getLines().toList
        lines.foreach {
          case Regex(ts, message) => {
            val timeStamp = ts.toLong
            timeStamp should be >= previous
            previous = timeStamp
          }
        }
        lines.length should be(threads.length * iterations)
      }
    }
  }
}

object AsynchronousLoggingSpec {
  val format = formatter"$timeStamp - $message$newLine"
}
{'fraction_non_alphanumeric': 0.0998719590268886, 'fraction_numerical': 0.006402048655569782, 'mean_word_length': 2.3214285714285716, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3749842', 'n_tokens_mistral': 1151, 'n_tokens_neox': 1101, 'n_words': 273}