Use SLF4J for logging.
This commit is contained in:
parent
8bafd62e35
commit
2cc4928a99
17 changed files with 82 additions and 148 deletions
|
@ -17,6 +17,7 @@ dependencies {
|
|||
compile 'com.mobsandgeeks:adapter-kit:0.5.3'
|
||||
compile 'com.google.zxing:android-integration:3.2.1'
|
||||
compile 'com.google.zxing:core:3.2.1'
|
||||
compile 'org.slf4j:slf4j-android:1.7.21'
|
||||
compile project(path: ':core')
|
||||
androidTestCompile 'com.android.support:multidex-instrumentation:1.0.1',
|
||||
{ exclude module: 'multidex' }
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
package com.nutomic.ensichat
|
||||
|
||||
import android.support.multidex.MultiDexApplication
|
||||
import com.nutomic.ensichat.core.interfaces.Log
|
||||
import com.nutomic.ensichat.util.{Logging, PRNGFixes}
|
||||
import com.nutomic.ensichat.util.PRNGFixes
|
||||
|
||||
class App extends MultiDexApplication {
|
||||
|
||||
override def onCreate(): Unit = {
|
||||
super.onCreate()
|
||||
Log.setLogInstance(new Logging())
|
||||
PRNGFixes.apply()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
package com.nutomic.ensichat.util
|
||||
|
||||
import android.util
|
||||
import com.nutomic.ensichat.core.interfaces.Log
|
||||
|
||||
class Logging extends Log {
|
||||
|
||||
def v(tag: String, message: String, tr: Throwable = null) = util.Log.v(tag, message, tr)
|
||||
def d(tag: String, message: String, tr: Throwable = null) = util.Log.d(tag, message, tr)
|
||||
def i(tag: String, message: String, tr: Throwable = null) = util.Log.i(tag, message, tr)
|
||||
def w(tag: String, message: String, tr: Throwable = null) = util.Log.w(tag, message, tr)
|
||||
def e(tag: String, message: String, tr: Throwable = null) = util.Log.e(tag, message, tr)
|
||||
}
|
|
@ -4,6 +4,7 @@ dependencies {
|
|||
compile 'org.scala-lang:scala-library:2.11.7'
|
||||
compile 'com.h2database:h2:1.4.191'
|
||||
compile 'com.typesafe.slick:slick_2.11:3.1.1'
|
||||
compile 'com.typesafe.scala-logging:scala-logging_2.11:3.4.0'
|
||||
testCompile 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
|
|
15
core/src/main/resources/logback.xml
Normal file
15
core/src/main/resources/logback.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<target>System.out</target>
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="slick" level="INFO" />
|
||||
|
||||
<root level="DEBUG">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
</root>
|
||||
</configuration>
|
|
@ -7,6 +7,7 @@ import com.nutomic.ensichat.core.header.ContentHeader
|
|||
import com.nutomic.ensichat.core.interfaces._
|
||||
import com.nutomic.ensichat.core.internet.InternetInterface
|
||||
import com.nutomic.ensichat.core.util.{Database, FutureHelper}
|
||||
import com.typesafe.scalalogging.Logger
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
||||
|
@ -20,7 +21,7 @@ final class ConnectionHandler(settings: SettingsInterface, database: Database,
|
|||
callbacks: CallbackInterface, crypto: Crypto,
|
||||
maxInternetConnections: Int) {
|
||||
|
||||
private val Tag = "ConnectionHandler"
|
||||
private val logger = Logger(this.getClass)
|
||||
|
||||
private var transmissionInterfaces = Set[TransmissionInterface]()
|
||||
|
||||
|
@ -45,8 +46,8 @@ final class ConnectionHandler(settings: SettingsInterface, database: Database,
|
|||
additionalInterfaces.foreach(transmissionInterfaces += _)
|
||||
FutureHelper {
|
||||
crypto.generateLocalKeys()
|
||||
Log.i(Tag, "Service started, address is " + crypto.localAddress)
|
||||
Log.i(Tag, "Local user is " + settings.get(SettingsInterface.KeyUserName, "none") +
|
||||
logger.info("Service started, address is " + crypto.localAddress)
|
||||
logger.info("Local user is " + settings.get(SettingsInterface.KeyUserName, "none") +
|
||||
" with status '" + settings.get(SettingsInterface.KeyUserStatus, "") + "'")
|
||||
transmissionInterfaces += new InternetInterface(this, crypto, settings, maxInternetConnections)
|
||||
transmissionInterfaces.foreach(_.create())
|
||||
|
@ -83,11 +84,11 @@ final class ConnectionHandler(settings: SettingsInterface, database: Database,
|
|||
*/
|
||||
def onMessageReceived(msg: Message): Unit = {
|
||||
if (router.isMessageSeen(msg)) {
|
||||
Log.v(Tag, "Ignoring message from " + msg.header.origin + " that we already received")
|
||||
logger.trace("Ignoring message from " + msg.header.origin + " that we already received")
|
||||
} else if (msg.header.target == crypto.localAddress) {
|
||||
crypto.verifyAndDecrypt(msg) match {
|
||||
case Some(m) => onNewMessage(m)
|
||||
case None => Log.i(Tag, "Ignoring message with invalid signature from " + msg.header.origin)
|
||||
case None => logger.info("Ignoring message with invalid signature from " + msg.header.origin)
|
||||
}
|
||||
} else {
|
||||
router.forwardMessage(msg)
|
||||
|
@ -127,34 +128,34 @@ final class ConnectionHandler(settings: SettingsInterface, database: Database,
|
|||
val maxConnections = settings.get(SettingsInterface.KeyMaxConnections,
|
||||
SettingsInterface.DefaultMaxConnections.toString).toInt
|
||||
if (connections().size == maxConnections) {
|
||||
Log.i(Tag, "Maximum number of connections reached")
|
||||
logger.info("Maximum number of connections reached")
|
||||
return false
|
||||
}
|
||||
|
||||
val info = msg.body.asInstanceOf[ConnectionInfo]
|
||||
val sender = crypto.calculateAddress(info.key)
|
||||
if (sender == Address.Broadcast || sender == Address.Null) {
|
||||
Log.i(Tag, "Ignoring ConnectionInfo message with invalid sender " + sender)
|
||||
logger.info("Ignoring ConnectionInfo message with invalid sender " + sender)
|
||||
return false
|
||||
}
|
||||
|
||||
if (crypto.havePublicKey(sender) && !crypto.verify(msg, Option(crypto.getPublicKey(sender)))) {
|
||||
Log.i(Tag, "Ignoring ConnectionInfo message with invalid signature")
|
||||
logger.info("Ignoring ConnectionInfo message with invalid signature")
|
||||
return false
|
||||
}
|
||||
|
||||
synchronized {
|
||||
if (!crypto.havePublicKey(sender)) {
|
||||
crypto.addPublicKey(sender, info.key)
|
||||
Log.i(Tag, "Added public key for new device " + sender.toString)
|
||||
logger.info("Added public key for new device " + sender.toString)
|
||||
}
|
||||
}
|
||||
|
||||
// Log with username if we know it.
|
||||
if (allKnownUsers().map(_.address).contains(sender))
|
||||
Log.i(Tag, "Node " + getUser(sender).name + " (" + sender + ") connected")
|
||||
logger.info("Node " + getUser(sender).name + " (" + sender + ") connected")
|
||||
else
|
||||
Log.i(Tag, "Node " + sender + " connected")
|
||||
logger.info("Node " + sender + " connected")
|
||||
|
||||
sendTo(sender, new UserInfo(settings.get(SettingsInterface.KeyUserName, ""),
|
||||
settings.get(SettingsInterface.KeyUserStatus, "")))
|
||||
|
|
|
@ -9,7 +9,8 @@ import javax.crypto.{Cipher, CipherOutputStream, KeyGenerator, SecretKey}
|
|||
import com.nutomic.ensichat.core.Crypto._
|
||||
import com.nutomic.ensichat.core.body._
|
||||
import com.nutomic.ensichat.core.header.ContentHeader
|
||||
import com.nutomic.ensichat.core.interfaces.{Log, SettingsInterface}
|
||||
import com.nutomic.ensichat.core.interfaces.SettingsInterface
|
||||
import com.typesafe.scalalogging.Logger
|
||||
|
||||
object Crypto {
|
||||
|
||||
|
@ -76,7 +77,7 @@ object Crypto {
|
|||
*/
|
||||
class Crypto(settings: SettingsInterface, keyFolder: File) {
|
||||
|
||||
private val Tag = "Crypto"
|
||||
private val logger = Logger(this.getClass)
|
||||
|
||||
/**
|
||||
* Generates a new key pair using [[keyFolder]] with [[PublicKeySize]] bits and stores the
|
||||
|
@ -104,7 +105,7 @@ class Crypto(settings: SettingsInterface, keyFolder: File) {
|
|||
|
||||
saveKey(PrivateKeyAlias, keyPair.getPrivate)
|
||||
saveKey(PublicKeyAlias, keyPair.getPublic)
|
||||
Log.i(Tag, "Generated cryptographic keys, address is " + address)
|
||||
logger.info("Generated cryptographic keys, address is " + address)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,7 +185,7 @@ class Crypto(settings: SettingsInterface, keyFolder: File) {
|
|||
fos = Option(new FileOutputStream(path))
|
||||
fos.foreach(_.write(key.getEncoded))
|
||||
} catch {
|
||||
case e: IOException => Log.w(Tag, "Failed to save key for alias " + alias, e)
|
||||
case e: IOException => logger.warn("Failed to save key for alias " + alias, e)
|
||||
} finally {
|
||||
fos.foreach(_.close())
|
||||
}
|
||||
|
@ -212,7 +213,7 @@ class Crypto(settings: SettingsInterface, keyFolder: File) {
|
|||
data = new Array[Byte](path.length().asInstanceOf[Int])
|
||||
fis.foreach(_.read(data))
|
||||
} catch {
|
||||
case e: IOException => Log.e(Tag, "Failed to load key for alias " + alias, e)
|
||||
case e: IOException => logger.error("Failed to load key for alias " + alias, e)
|
||||
} finally {
|
||||
fis.foreach(_.close())
|
||||
}
|
||||
|
@ -240,7 +241,7 @@ class Crypto(settings: SettingsInterface, keyFolder: File) {
|
|||
None
|
||||
} catch {
|
||||
case e: InvalidKeyException =>
|
||||
Log.w(Tag, "Failed to verify or decrypt message", e)
|
||||
logger.warn("Failed to verify or decrypt message", e)
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
package com.nutomic.ensichat.core.interfaces
|
||||
|
||||
object Log {
|
||||
|
||||
def setLogInstance(log: Log) = instance = Option(log)
|
||||
|
||||
private var instance: Option[Log] = None
|
||||
|
||||
def v(tag: String, message: String, tr: Throwable = null) = instance.foreach(_.v(tag, message, tr))
|
||||
def d(tag: String, message: String, tr: Throwable = null) = instance.foreach(_.d(tag, message, tr))
|
||||
def i(tag: String, message: String, tr: Throwable = null) = instance.foreach(_.i(tag, message, tr))
|
||||
def w(tag: String, message: String, tr: Throwable = null) = instance.foreach(_.w(tag, message, tr))
|
||||
def e(tag: String, message: String, tr: Throwable = null) = instance.foreach(_.e(tag, message, tr))
|
||||
|
||||
}
|
||||
|
||||
trait Log {
|
||||
|
||||
def v(tag: String, message: String, tr: Throwable = null)
|
||||
def d(tag: String, message: String, tr: Throwable = null)
|
||||
def i(tag: String, message: String, tr: Throwable = null)
|
||||
def w(tag: String, message: String, tr: Throwable = null)
|
||||
def e(tag: String, message: String, tr: Throwable = null)
|
||||
|
||||
}
|
|
@ -6,8 +6,8 @@ import java.net.{InetAddress, Socket}
|
|||
import com.nutomic.ensichat.core.Message.ReadMessageException
|
||||
import com.nutomic.ensichat.core.body.ConnectionInfo
|
||||
import com.nutomic.ensichat.core.header.MessageHeader
|
||||
import com.nutomic.ensichat.core.interfaces.Log
|
||||
import com.nutomic.ensichat.core.{Address, Crypto, Message}
|
||||
import com.typesafe.scalalogging.Logger
|
||||
|
||||
/**
|
||||
* Encapsulates an active connection to another node.
|
||||
|
@ -15,14 +15,14 @@ import com.nutomic.ensichat.core.{Address, Crypto, Message}
|
|||
class InternetConnectionThread(socket: Socket, crypto: Crypto, onDisconnected: (InternetConnectionThread) => Unit,
|
||||
onReceive: (Message, InternetConnectionThread) => Unit) extends Thread {
|
||||
|
||||
private val Tag = "InternetConnectionThread"
|
||||
private val logger = Logger(this.getClass)
|
||||
|
||||
private val inStream: InputStream =
|
||||
try {
|
||||
socket.getInputStream
|
||||
} catch {
|
||||
case e: IOException =>
|
||||
Log.e(Tag, "Failed to open stream", e)
|
||||
logger.error("Failed to open stream", e)
|
||||
close()
|
||||
null
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class InternetConnectionThread(socket: Socket, crypto: Crypto, onDisconnected: (
|
|||
socket.getOutputStream
|
||||
} catch {
|
||||
case e: IOException =>
|
||||
Log.e(Tag, "Failed to open stream", e)
|
||||
logger.error("Failed to open stream", e)
|
||||
close()
|
||||
null
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ class InternetConnectionThread(socket: Socket, crypto: Crypto, onDisconnected: (
|
|||
}
|
||||
|
||||
override def run(): Unit = {
|
||||
Log.i(Tag, "Connection opened to " + socket.getInetAddress)
|
||||
logger.info("Connection opened to " + socket.getInetAddress)
|
||||
|
||||
send(crypto.sign(new Message(new MessageHeader(ConnectionInfo.Type,
|
||||
Address.Null, Address.Null, 0), new ConnectionInfo(crypto.getLocalPublicKey))))
|
||||
|
@ -51,13 +51,13 @@ class InternetConnectionThread(socket: Socket, crypto: Crypto, onDisconnected: (
|
|||
socket.setKeepAlive(true)
|
||||
while (socket.isConnected) {
|
||||
val msg = Message.read(inStream)
|
||||
Log.v(Tag, "Received " + msg)
|
||||
logger.trace("Received " + msg)
|
||||
|
||||
onReceive(msg, this)
|
||||
}
|
||||
} catch {
|
||||
case e @ (_: ReadMessageException | _: IOException) =>
|
||||
Log.w(Tag, "Failed to read incoming message", e)
|
||||
logger.warn("Failed to read incoming message", e)
|
||||
close()
|
||||
return
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class InternetConnectionThread(socket: Socket, crypto: Crypto, onDisconnected: (
|
|||
try {
|
||||
outStream.write(msg.write)
|
||||
} catch {
|
||||
case e: IOException => Log.e(Tag, "Failed to write message", e)
|
||||
case e: IOException => logger.error("Failed to write message", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,9 +76,9 @@ class InternetConnectionThread(socket: Socket, crypto: Crypto, onDisconnected: (
|
|||
try {
|
||||
socket.close()
|
||||
} catch {
|
||||
case e: IOException => Log.w(Tag, "Failed to close socket", e)
|
||||
case e: IOException => logger.warn("Failed to close socket", e)
|
||||
}
|
||||
Log.d(Tag, "Connection to " + socket.getInetAddress + " closed")
|
||||
logger.debug("Connection to " + socket.getInetAddress + " closed")
|
||||
onDisconnected(this)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
package com.nutomic.ensichat.core.internet
|
||||
|
||||
import java.io.IOException
|
||||
import java.net.{InetAddress, Socket}
|
||||
|
||||
import com.nutomic.ensichat.core.body.ConnectionInfo
|
||||
import com.nutomic.ensichat.core.interfaces.{Log, SettingsInterface, TransmissionInterface}
|
||||
import com.nutomic.ensichat.core.interfaces.{SettingsInterface, TransmissionInterface}
|
||||
import com.nutomic.ensichat.core.util.FutureHelper
|
||||
import com.nutomic.ensichat.core.{Address, ConnectionHandler, Crypto, Message}
|
||||
import com.typesafe.scalalogging.Logger
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import scala.util.Random
|
||||
|
||||
object InternetInterface {
|
||||
|
@ -26,7 +27,7 @@ class InternetInterface(connectionHandler: ConnectionHandler, crypto: Crypto,
|
|||
settings: SettingsInterface, maxConnections: Int)
|
||||
extends TransmissionInterface {
|
||||
|
||||
private val Tag = "InternetInterface"
|
||||
private val logger = Logger(this.getClass)
|
||||
|
||||
private lazy val serverThread =
|
||||
new InternetServerThread(crypto, onConnected, onDisconnected, onReceiveMessage)
|
||||
|
@ -83,15 +84,14 @@ class InternetInterface(connectionHandler: ConnectionHandler, crypto: Crypto,
|
|||
* Opens connection to the specified IP address in client mode.
|
||||
*/
|
||||
private def openConnection(address: String, port: Int): Unit = {
|
||||
Log.i(Tag, s"Attempting connection to $address:$port")
|
||||
try {
|
||||
logger.info(s"Attempting connection to $address:$port")
|
||||
Future {
|
||||
val socket = new Socket(InetAddress.getByName(address), port)
|
||||
val ct = new InternetConnectionThread(socket, crypto, onDisconnected, onReceiveMessage)
|
||||
connections += ct
|
||||
ct.start()
|
||||
} catch {
|
||||
case e: IOException =>
|
||||
Log.w(Tag, "Failed to open connection to " + address + ":" + port, e)
|
||||
}.onFailure { case e =>
|
||||
logger.warn("Failed to open connection to " + address + ":" + port, e)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ class InternetInterface(connectionHandler: ConnectionHandler, crypto: Crypto,
|
|||
|
||||
private def onDisconnected(connectionThread: InternetConnectionThread): Unit = {
|
||||
addressDeviceMap.find(_._2 == connectionThread).foreach { ad =>
|
||||
Log.d(Tag, "Connection closed to " + ad._1)
|
||||
logger.trace("Connection closed to " + ad._1)
|
||||
connections -= connectionThread
|
||||
addressDeviceMap -= ad._1
|
||||
connectionHandler.onConnectionClosed()
|
||||
|
@ -112,7 +112,7 @@ class InternetInterface(connectionHandler: ConnectionHandler, crypto: Crypto,
|
|||
case info: ConnectionInfo =>
|
||||
val address = crypto.calculateAddress(info.key)
|
||||
if (address == crypto.localAddress) {
|
||||
Log.i(Tag, "Address " + address + " is me, not connecting to myself")
|
||||
logger.info("Address " + address + " is me, not connecting to myself")
|
||||
thread.close()
|
||||
return
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ class InternetInterface(connectionHandler: ConnectionHandler, crypto: Crypto,
|
|||
|
||||
def connectionChanged(): Unit = {
|
||||
FutureHelper {
|
||||
Log.i(Tag, "Network has changed. Closing all connections and connecting to bootstrap nodes again")
|
||||
logger.info("Network has changed. Closing all connections and connecting to bootstrap nodes again")
|
||||
connections.foreach(_.close())
|
||||
openAllConnections(maxConnections)
|
||||
}
|
||||
|
|
|
@ -3,19 +3,19 @@ package com.nutomic.ensichat.core.internet
|
|||
import java.io.IOException
|
||||
import java.net.ServerSocket
|
||||
|
||||
import com.nutomic.ensichat.core.interfaces.Log
|
||||
import com.nutomic.ensichat.core.{Crypto, Message}
|
||||
import com.typesafe.scalalogging.Logger
|
||||
|
||||
class InternetServerThread(crypto: Crypto, onConnected: (InternetConnectionThread) => Unit,
|
||||
onDisconnected: (InternetConnectionThread) => Unit, onReceive: (Message, InternetConnectionThread) => Unit) extends Thread {
|
||||
|
||||
private val Tag = "InternetServerThread"
|
||||
private val logger = Logger(this.getClass)
|
||||
|
||||
private lazy val socket: Option[ServerSocket] = try {
|
||||
Option(new ServerSocket(InternetInterface.ServerPort))
|
||||
} catch {
|
||||
case e: IOException =>
|
||||
Log.w(Tag, "Failed to create server socket", e)
|
||||
logger.warn("Failed to create server socket", e)
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ class InternetServerThread(crypto: Crypto, onConnected: (InternetConnectionThrea
|
|||
connection.start()
|
||||
}
|
||||
} catch {
|
||||
case e: IOException => Log.w(Tag, "Failed to accept connection", e)
|
||||
case e: IOException => logger.warn("Failed to accept connection", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ class InternetServerThread(crypto: Crypto, onConnected: (InternetConnectionThrea
|
|||
try {
|
||||
socket.get.close()
|
||||
} catch {
|
||||
case e: IOException => Log.w(Tag, "Failed to close socket", e)
|
||||
case e: IOException => logger.warn("Failed to close socket", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,10 +5,10 @@ import java.util.Date
|
|||
|
||||
import com.nutomic.ensichat.core.body.Text
|
||||
import com.nutomic.ensichat.core.header.ContentHeader
|
||||
import com.nutomic.ensichat.core.interfaces.{Log, CallbackInterface}
|
||||
import com.nutomic.ensichat.core.interfaces.CallbackInterface
|
||||
import com.nutomic.ensichat.core.{Address, Message, User}
|
||||
import com.typesafe.scalalogging.Logger
|
||||
import slick.driver.H2Driver.api._
|
||||
import slick.jdbc.meta.MTable
|
||||
|
||||
import scala.concurrent.Await
|
||||
import scala.concurrent.duration.Duration
|
||||
|
@ -21,7 +21,7 @@ import scala.concurrent.duration.Duration
|
|||
*/
|
||||
class Database(path: File, callbackInterface: CallbackInterface) {
|
||||
|
||||
private val Tag = "Database"
|
||||
private val logger = Logger(this.getClass)
|
||||
|
||||
private class Messages(tag: Tag) extends Table[Message](tag, "MESSAGES") {
|
||||
def id = primaryKey("id", (origin, messageId))
|
||||
|
@ -63,7 +63,7 @@ class Database(path: File, callbackInterface: CallbackInterface) {
|
|||
// H2 appends a .mv.db suffix to the path which we can't change, so we have to check that file.
|
||||
val dbFile = new File(path.getAbsolutePath + ".mv.db")
|
||||
if (!dbFile.exists()) {
|
||||
Log.i(Tag, "Database does not exist, creating tables")
|
||||
logger.info("Database does not exist, creating tables")
|
||||
Await.result(db.run((messages.schema ++ contacts.schema).create), Duration.Inf)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.nutomic.ensichat.core.util
|
||||
|
||||
import com.nutomic.ensichat.core.interfaces.Log
|
||||
import com.typesafe.scalalogging.Logger
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
|
@ -11,7 +11,7 @@ import scala.concurrent.{ExecutionContext, Future}
|
|||
*/
|
||||
object FutureHelper {
|
||||
|
||||
private val Tag = "FutureHelper"
|
||||
private val logger = Logger(this.getClass)
|
||||
|
||||
def apply[A](action: => A)(implicit executor: ExecutionContext): Future[A] = {
|
||||
val f = Future(action)
|
||||
|
@ -20,7 +20,7 @@ object FutureHelper {
|
|||
// HACK: Android does not close app when crash occurs in background thread, and there's no
|
||||
// cross-platform way to execute on the foreground thread.
|
||||
// We use this to make sure exceptions are not hidden in the logs.
|
||||
Log.e(Tag, "Exception in Future", e)
|
||||
logger.error("Exception in Future", e)
|
||||
//System.exit(-1)
|
||||
}
|
||||
f
|
||||
|
|
|
@ -5,6 +5,7 @@ dependencies {
|
|||
compile 'org.scala-lang:scala-library:2.11.7'
|
||||
compile project(path: ':core')
|
||||
compile 'com.github.scopt:scopt_2.10:3.3.0'
|
||||
compile 'ch.qos.logback:logback-classic:1.1.7'
|
||||
}
|
||||
|
||||
mainClassName = 'com.nutomic.ensichat.server.Main'
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
package com.nutomic.ensichat.server
|
||||
|
||||
import java.io.{PrintWriter, StringWriter}
|
||||
import java.text.DateFormat
|
||||
import java.util.{Date, Locale}
|
||||
|
||||
import com.nutomic.ensichat.core.interfaces.Log
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
class Logging extends Log {
|
||||
|
||||
private val logs = new mutable.Queue[String]()
|
||||
|
||||
def dequeue(): Seq[String] = logs.dequeueAll((String) => true)
|
||||
|
||||
private def enqueue(tag: String, message: String, tr: Option[Throwable]): Unit = {
|
||||
val df = DateFormat.getTimeInstance(DateFormat.DEFAULT, Locale.UK)
|
||||
val throwableString = tr.map { tr =>
|
||||
val sw = new StringWriter()
|
||||
tr.printStackTrace(new PrintWriter(sw))
|
||||
"\n" + sw.toString
|
||||
}
|
||||
logs.enqueue(df.format(new Date()) + " " + tag + ": " + message + throwableString.getOrElse(""))
|
||||
}
|
||||
|
||||
def v(tag: String, message: String, tr: Throwable = null): Unit =
|
||||
enqueue("V/" + tag, message, Option(tr))
|
||||
|
||||
def d(tag: String, message: String, tr: Throwable = null): Unit =
|
||||
enqueue("D/" + tag, message, Option(tr))
|
||||
|
||||
def i(tag: String, message: String, tr: Throwable = null): Unit =
|
||||
enqueue("I/" + tag, message, Option(tr))
|
||||
|
||||
def w(tag: String, message: String, tr: Throwable = null): Unit =
|
||||
enqueue("W/" + tag, message, Option(tr))
|
||||
|
||||
def e(tag: String, message: String, tr: Throwable = null): Unit =
|
||||
enqueue("E/" + tag, message, Option(tr))
|
||||
|
||||
}
|
|
@ -5,24 +5,21 @@ import java.nio.file.Paths
|
|||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import com.nutomic.ensichat.core.body.Text
|
||||
import com.nutomic.ensichat.core.interfaces.SettingsInterface._
|
||||
import com.nutomic.ensichat.core.interfaces.{CallbackInterface, Log, SettingsInterface}
|
||||
import com.nutomic.ensichat.core.interfaces.{CallbackInterface, SettingsInterface}
|
||||
import com.nutomic.ensichat.core.util.Database
|
||||
import com.nutomic.ensichat.core.{ConnectionHandler, Crypto, Message}
|
||||
import com.typesafe.scalalogging.Logger
|
||||
import scopt.OptionParser
|
||||
|
||||
object Main extends App with CallbackInterface {
|
||||
|
||||
private val Tag = "Main"
|
||||
private val logger = Logger(this.getClass)
|
||||
|
||||
private val ConfigFolder = Paths.get("").toFile.getAbsoluteFile
|
||||
private val ConfigFile = new File(ConfigFolder, "config.properties")
|
||||
private val DatabaseFile = new File(ConfigFolder, "database")
|
||||
private val KeyFolder = new File(ConfigFolder, "keys")
|
||||
|
||||
private val LogInterval = TimeUnit.SECONDS.toMillis(1)
|
||||
|
||||
private lazy val logInstance = new Logging()
|
||||
private lazy val settings = new Settings(ConfigFile)
|
||||
private lazy val crypto = new Crypto(settings, KeyFolder)
|
||||
private lazy val database = new Database(DatabaseFile, this)
|
||||
|
@ -38,7 +35,6 @@ object Main extends App with CallbackInterface {
|
|||
private def init(): Unit = {
|
||||
ConfigFolder.mkdirs()
|
||||
KeyFolder.mkdirs()
|
||||
Log.setLogInstance(logInstance)
|
||||
sys.addShutdownHook(connectionHandler.stop())
|
||||
|
||||
val parser = new OptionParser[Config]("ensichat") {
|
||||
|
@ -64,8 +60,7 @@ object Main extends App with CallbackInterface {
|
|||
|
||||
// Keep alive and print logs
|
||||
while (true) {
|
||||
Thread.sleep(LogInterval)
|
||||
logInstance.dequeue().foreach(System.out.println)
|
||||
Thread.sleep(TimeUnit.SECONDS.toMillis(1))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,9 +73,9 @@ object Main extends App with CallbackInterface {
|
|||
val address = msg.header.origin
|
||||
val name = connectionHandler.getUser(address).name
|
||||
connectionHandler.sendTo(address, new Text("Hello " + name))
|
||||
Log.i(Tag, "Received text: " + text.text)
|
||||
logger.info("Received text: " + text.text)
|
||||
case _ =>
|
||||
Log.i(Tag, "Received msg: " + msg.body)
|
||||
logger.info("Received msg: " + msg.body)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,13 +3,14 @@ package com.nutomic.ensichat.server
|
|||
import java.io._
|
||||
import java.util.Properties
|
||||
|
||||
import com.nutomic.ensichat.core.interfaces.{Log, SettingsInterface}
|
||||
import com.nutomic.ensichat.core.interfaces.SettingsInterface
|
||||
import com.typesafe.scalalogging.Logger
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
|
||||
class Settings(file: File) extends SettingsInterface {
|
||||
|
||||
private val Tag = "Settings"
|
||||
private val logger = Logger(this.getClass)
|
||||
|
||||
if (!file.exists()) {
|
||||
file.createNewFile()
|
||||
|
@ -23,7 +24,7 @@ class Settings(file: File) extends SettingsInterface {
|
|||
p.load(fis)
|
||||
fis.close()
|
||||
} catch {
|
||||
case e: IOException => Log.w(Tag, "Failed to load settings from " + file, e)
|
||||
case e: IOException => logger.warn("Failed to load settings from " + file, e)
|
||||
}
|
||||
p
|
||||
}
|
||||
|
@ -35,7 +36,7 @@ class Settings(file: File) extends SettingsInterface {
|
|||
props.store(fos, "")
|
||||
fos.close()
|
||||
} catch {
|
||||
case e: IOException => Log.w(Tag, "Failed to write preference for key " + key, e)
|
||||
case e: IOException => logger.warn("Failed to write preference for key " + key, e)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue