Compare commits
1 Commits
FightSyste
...
new-loggin
| Author | SHA1 | Date | |
|---|---|---|---|
|
ec41111054
|
@@ -24,4 +24,5 @@ plugins {
|
|||||||
dependencies {
|
dependencies {
|
||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
testImplementation(libs.hamcrest)
|
testImplementation(libs.hamcrest)
|
||||||
|
compileOnly(project(":CommonCore:SQL"))
|
||||||
}
|
}
|
||||||
22
CommonCore/SQL/src/de/steamwar/ServerInfo.kt
Normal file
22
CommonCore/SQL/src/de/steamwar/ServerInfo.kt
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar
|
||||||
|
|
||||||
|
data class ServerInfo(val name: String, val version: Int, val checkpointed: Boolean)
|
||||||
71
CommonCore/SQL/src/de/steamwar/logger/LogEntry.kt
Normal file
71
CommonCore/SQL/src/de/steamwar/logger/LogEntry.kt
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.logger
|
||||||
|
|
||||||
|
import de.steamwar.sql.AuditLog
|
||||||
|
import de.steamwar.sql.AuditLogTable
|
||||||
|
import de.steamwar.sql.SQLWrapper
|
||||||
|
import de.steamwar.sql.SteamwarUser
|
||||||
|
import de.steamwar.sql.internal.useDb
|
||||||
|
import org.jetbrains.exposed.v1.jdbc.insertIgnore
|
||||||
|
|
||||||
|
class LogEntry(val type: AuditLog.Type, val user: SteamwarUser) {
|
||||||
|
private val start = System.currentTimeMillis()
|
||||||
|
|
||||||
|
var text: String = ""
|
||||||
|
var arguments: String = ""
|
||||||
|
|
||||||
|
private var exceptionType: String? = null
|
||||||
|
private var exceptionText: String? = null
|
||||||
|
private var exceptionStacktrace: String? = null
|
||||||
|
|
||||||
|
private var owner: SteamwarUser? = null
|
||||||
|
|
||||||
|
fun addException(e: Throwable) {
|
||||||
|
exceptionType = e.javaClass.name
|
||||||
|
exceptionText = e.message
|
||||||
|
exceptionStacktrace = e.stackTraceToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addServerOwner(owner: SteamwarUser) {
|
||||||
|
this.owner = owner
|
||||||
|
}
|
||||||
|
|
||||||
|
fun finish() {
|
||||||
|
val end = System.currentTimeMillis()
|
||||||
|
val info = SQLWrapper.impl.serverInfo
|
||||||
|
useDb {
|
||||||
|
AuditLogTable.insertIgnore {
|
||||||
|
it[this.action] = type
|
||||||
|
it[this.actor] = user.getId()
|
||||||
|
it[this.actionText] = text
|
||||||
|
it[this.actionArguments] = arguments
|
||||||
|
it[this.duration] = end - start
|
||||||
|
it[this.errorType] = exceptionType
|
||||||
|
it[this.errorText] = exceptionText
|
||||||
|
it[this.stackTrace] = exceptionStacktrace
|
||||||
|
it[this.server] = info.name
|
||||||
|
it[this.checkpointed] = info.checkpointed
|
||||||
|
it[this.duration] = end - start
|
||||||
|
it[this.serverOwner] = owner?.getId()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
27
CommonCore/SQL/src/de/steamwar/logger/SWLogger.kt
Normal file
27
CommonCore/SQL/src/de/steamwar/logger/SWLogger.kt
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.logger
|
||||||
|
|
||||||
|
import de.steamwar.sql.AuditLog
|
||||||
|
import de.steamwar.sql.SteamwarUser
|
||||||
|
|
||||||
|
object SWLogger {
|
||||||
|
fun startCommand(user: SteamwarUser) = LogEntry(AuditLog.Type.COMMAND, user)
|
||||||
|
}
|
||||||
@@ -19,94 +19,47 @@
|
|||||||
|
|
||||||
package de.steamwar.sql
|
package de.steamwar.sql
|
||||||
|
|
||||||
import de.steamwar.sql.internal.useDb
|
|
||||||
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
import org.jetbrains.exposed.v1.core.dao.id.EntityID
|
||||||
import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
|
import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
|
||||||
import org.jetbrains.exposed.v1.dao.IntEntity
|
import org.jetbrains.exposed.v1.dao.IntEntity
|
||||||
import org.jetbrains.exposed.v1.dao.IntEntityClass
|
import org.jetbrains.exposed.v1.dao.IntEntityClass
|
||||||
import org.jetbrains.exposed.v1.javatime.timestamp
|
import org.jetbrains.exposed.v1.javatime.timestamp
|
||||||
import java.time.Instant
|
|
||||||
|
|
||||||
object AuditLogTable: IntIdTable("AuditLog", "AuditLogId") {
|
object AuditLogTable: IntIdTable("AuditLog", "AuditLogId") {
|
||||||
val time = timestamp("Time")
|
val time = timestamp("Time")
|
||||||
val server = varchar("ServerName", 255)
|
val server = varchar("ServerName", 255)
|
||||||
val serverOwner = reference("ServerOwner", SteamwarUserTable).nullable()
|
val serverType = varchar("ServerType", 255)
|
||||||
|
val serverOwner = optReference("ServerOwner", SteamwarUserTable)
|
||||||
|
val checkpointed = bool("Checkpointed")
|
||||||
val actor = reference("Actor", SteamwarUserTable)
|
val actor = reference("Actor", SteamwarUserTable)
|
||||||
val action = enumerationByName("ActionType", 255, AuditLog.Type::class)
|
val action = enumerationByName("ActionType", 255, AuditLog.Type::class)
|
||||||
val actionText = text("ActionText")
|
val actionText = text("ActionText")
|
||||||
|
val actionArguments = text("ActionArguments")
|
||||||
|
val duration = long("Duration")
|
||||||
|
val errorType = text("ErrorType").nullable()
|
||||||
|
val errorText = text("ErrorText").nullable()
|
||||||
|
val stackTrace = text("StackTrace").nullable()
|
||||||
}
|
}
|
||||||
|
|
||||||
class AuditLog(id: EntityID<Int>): IntEntity(id) {
|
class AuditLog(id: EntityID<Int>): IntEntity(id) {
|
||||||
companion object: IntEntityClass<AuditLog>(AuditLogTable) {
|
companion object: IntEntityClass<AuditLog>(AuditLogTable) {
|
||||||
const val SERVER_NAME_VELOCITY: String = "Velocity"
|
@JvmField
|
||||||
|
val SERVER_NAME_VELOCITY: String = "Velocity"
|
||||||
private fun create(
|
|
||||||
serverName: String,
|
|
||||||
serverOwner: SteamwarUser?,
|
|
||||||
actor: SteamwarUser,
|
|
||||||
actionType: Type,
|
|
||||||
text: String = ""
|
|
||||||
) = useDb {
|
|
||||||
new {
|
|
||||||
this.time = Instant.now()
|
|
||||||
this.server = serverName
|
|
||||||
this.serverOwner = serverOwner?.id
|
|
||||||
this.actor = actor.id
|
|
||||||
this.action = actionType
|
|
||||||
this.actionText = text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun createJoin(jointServerName: String, serverOwner: SteamwarUser?, joinedPlayer: SteamwarUser) = create(jointServerName, serverOwner, joinedPlayer, Type.JOIN)
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun createLeave(leftServerName: String, serverOwner: SteamwarUser?, joinedPlayer: SteamwarUser) = create(leftServerName, serverOwner, joinedPlayer, Type.LEAVE)
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun createCommand(serverName: String, serverOwner: SteamwarUser?, player: SteamwarUser?, command: String) = player?.let { create(serverName, serverOwner, it, Type.COMMAND, command) }
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun createSensitiveCommand(
|
|
||||||
serverName: String,
|
|
||||||
serverOwner: SteamwarUser?,
|
|
||||||
player: SteamwarUser?,
|
|
||||||
command: String
|
|
||||||
) = player?.let { create(serverName, serverOwner, it, Type.SENSITIVE_COMMAND, command) }
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun createChat(serverName: String, serverOwner: SteamwarUser?, chatter: SteamwarUser, chat: String) = create(serverName, serverOwner, chatter, Type.CHAT, chat)
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun createGuiOpen(serverName: String, serverOwner: SteamwarUser?, player: SteamwarUser, guiName: String) = create(serverName, serverOwner, player, Type.GUI_OPEN, guiName)
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun createGuiClick(
|
|
||||||
serverName: String,
|
|
||||||
serverOwner: SteamwarUser?,
|
|
||||||
player: SteamwarUser,
|
|
||||||
guiName: String,
|
|
||||||
clickType: String,
|
|
||||||
slot: Int,
|
|
||||||
itemName: String
|
|
||||||
) = create(
|
|
||||||
serverName,
|
|
||||||
serverOwner,
|
|
||||||
player,
|
|
||||||
Type.GUI_CLICK,
|
|
||||||
"Gui: $guiName\nSlot: $slot\nClickType: $clickType\nItemName: $itemName"
|
|
||||||
)
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun createGuiClose(serverName: String, serverOwner: SteamwarUser?, player: SteamwarUser, guiName: String) = create(serverName, serverOwner, player, Type.GUI_CLOSE, guiName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var time by AuditLogTable.time
|
var time by AuditLogTable.time
|
||||||
var server by AuditLogTable.server
|
var server by AuditLogTable.server
|
||||||
|
val serverType by AuditLogTable.serverType
|
||||||
var serverOwner by AuditLogTable.serverOwner
|
var serverOwner by AuditLogTable.serverOwner
|
||||||
var actor by AuditLogTable.actor
|
var actor by AuditLogTable.actor
|
||||||
|
var checkpointed by AuditLogTable.checkpointed
|
||||||
var action by AuditLogTable.action
|
var action by AuditLogTable.action
|
||||||
var actionText by AuditLogTable.actionText
|
var actionText by AuditLogTable.actionText
|
||||||
|
var actionArguments by AuditLogTable.actionArguments
|
||||||
|
var duration by AuditLogTable.duration
|
||||||
|
var errorType by AuditLogTable.errorType
|
||||||
|
var errorText by AuditLogTable.errorText
|
||||||
|
var stackTrace by AuditLogTable.stackTrace
|
||||||
|
|
||||||
enum class Type {
|
enum class Type {
|
||||||
JOIN,
|
JOIN,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
package de.steamwar.sql;
|
package de.steamwar.sql;
|
||||||
|
|
||||||
import de.steamwar.ImplementationProvider;
|
import de.steamwar.ImplementationProvider;
|
||||||
|
import de.steamwar.ServerInfo;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -40,4 +41,6 @@ public interface SQLWrapper<M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void additionalExceptionMetadata(StringBuilder builder);
|
void additionalExceptionMetadata(StringBuilder builder);
|
||||||
|
|
||||||
|
ServerInfo getServerInfo();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ object ExceptionTable: IntIdTable("Exception") {
|
|||||||
|
|
||||||
class SWException {
|
class SWException {
|
||||||
companion object {
|
companion object {
|
||||||
|
private val exceptionCache = HashSet<String>()
|
||||||
|
|
||||||
val cwd = System.getProperty("user.dir")
|
val cwd = System.getProperty("user.dir")
|
||||||
val serverName = File(cwd).name
|
val serverName = File(cwd).name
|
||||||
|
|
||||||
@@ -43,7 +45,9 @@ class SWException {
|
|||||||
fun init() = Unit
|
fun init() = Unit
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun log(message: String, stacktrace: String) = useDb {
|
fun log(message: String, stacktrace: String) = if (exceptionCache.contains(stacktrace)) Unit else useDb {
|
||||||
|
exceptionCache.add(stacktrace)
|
||||||
|
|
||||||
ExceptionTable.insert {
|
ExceptionTable.insert {
|
||||||
it[ExceptionTable.server] = serverName
|
it[ExceptionTable.server] = serverName
|
||||||
it[ExceptionTable.message] = generateMessage(message)
|
it[ExceptionTable.message] = generateMessage(message)
|
||||||
|
|||||||
@@ -19,9 +19,14 @@
|
|||||||
|
|
||||||
package de.steamwar.core;
|
package de.steamwar.core;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
public class CheckpointUtils {
|
public class CheckpointUtils {
|
||||||
private CheckpointUtils() {}
|
private CheckpointUtils() {}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static boolean restored = false;
|
||||||
|
|
||||||
public static void signalHandler() {
|
public static void signalHandler() {
|
||||||
try {
|
try {
|
||||||
CheckpointUtilsJ9.signalHandler();
|
CheckpointUtilsJ9.signalHandler();
|
||||||
@@ -33,6 +38,7 @@ public class CheckpointUtils {
|
|||||||
public static void freeze() {
|
public static void freeze() {
|
||||||
try {
|
try {
|
||||||
CheckpointUtilsJ9.freeze();
|
CheckpointUtilsJ9.freeze();
|
||||||
|
restored = true;
|
||||||
} catch (NoClassDefFoundError e) {
|
} catch (NoClassDefFoundError e) {
|
||||||
//ignore
|
//ignore
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
package de.steamwar.sql;
|
package de.steamwar.sql;
|
||||||
|
|
||||||
|
import de.steamwar.ServerInfo;
|
||||||
|
import de.steamwar.core.CheckpointUtils;
|
||||||
import de.steamwar.core.Core;
|
import de.steamwar.core.Core;
|
||||||
import de.steamwar.data.GameModeConfigUtils;
|
import de.steamwar.data.GameModeConfigUtils;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@@ -68,4 +70,9 @@ public class SQLWrapperImpl implements SQLWrapper<Material> {
|
|||||||
builder.append(world.getName()).append(" ");
|
builder.append(world.getName()).append(" ");
|
||||||
builder.append("\nServer: ").append(SERVER_VERSION);
|
builder.append("\nServer: ").append(SERVER_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerInfo getServerInfo() {
|
||||||
|
return new ServerInfo(Core.getServerName(), Core.getVersion(), CheckpointUtils.isRestored());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user