diff --git a/pom.xml b/pom.xml
index a78339f..fca2c08 100644
--- a/pom.xml
+++ b/pom.xml
@@ -33,12 +33,22 @@
org.apache.httpcomponents
httpclient
- 4.5
+ 4.5.13
- org.slf4j
- slf4j-simple
- 1.7.9
+ org.apache.logging.log4j
+ log4j-api
+ 2.17.2
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.17.2
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+ 2.17.2
com.sedmelluq
@@ -48,7 +58,7 @@
mysql
mysql-connector-java
- 8.0.28
+ 8.0.29
@@ -60,7 +70,7 @@
com.google.guava
guava
- 31.0.1-jre
+ 31.1-jre
@@ -78,6 +88,11 @@
bintray
https://jcenter.bintray.com
+
+ maven_central
+ Maven Central
+ https://repo.maven.apache.org/maven2/
+
diff --git a/src/main/java/moe/oko/Kiafumi/Kiafumi.java b/src/main/java/moe/oko/Kiafumi/Kiafumi.java
index fc48607..94e24e4 100644
--- a/src/main/java/moe/oko/Kiafumi/Kiafumi.java
+++ b/src/main/java/moe/oko/Kiafumi/Kiafumi.java
@@ -90,8 +90,6 @@ public class Kiafumi {
// All commands to be loaded on startup!
activeCommands = new CommandRegistrar().getCommandClasses();
- logger.info("Config load start...");
-
// Ensuring the configuration file is generated and/or exists.
if (!CONFIG_FILE.exists()) {
try (InputStream is = this.getClass().getClassLoader().getResourceAsStream("config.yml")) {
@@ -143,7 +141,6 @@ public class Kiafumi {
public void stop() {
var build = new EmbedBuilder()
.setColor(EmbedUI.FAILURE)
- .setAuthor("Kiafumi", null, Kiafumi.JDA.getSelfUser().getAvatarUrl())
.setTitle("Offline")
.setFooter(footer)
.setTimestamp(ZonedDateTime.now());
@@ -178,11 +175,10 @@ public class Kiafumi {
}
registerAllCommands();
- info("Loaded " + activeCommands.size() + " commands.");
+ info("Finished registering commands.");
var eb = new EmbedBuilder()
.setColor(EmbedUI.SUCCESS)
- .setAuthor("Kiafumi", null, Kiafumi.JDA.getSelfUser().getAvatarUrl())
.setTitle("Online")
.setFooter(footer)
.setTimestamp(ZonedDateTime.now());
@@ -194,6 +190,7 @@ public class Kiafumi {
*/
private void registerAllCommands() {
// Registers slash commands.
+ info("Registering commands for guilds.");
for(Guild guild : JDA.getGuilds()) {
registerForGuild(guild);
}
@@ -209,7 +206,7 @@ public class Kiafumi {
* @param guild - guild to have commands provided to
*/
public void registerForGuild(Guild guild) {
- info("Registering commands for guild [" + guild.getId() + "]");
+ debug("Registering commands for guild [" + guild.getName() + ":" + guild.getId() + "]");
int i = 0;
for(CommandClass cmd : activeCommands) {
for(CommandInfo ci : cmd.getSlashCommandInfo()) {
@@ -232,7 +229,7 @@ public class Kiafumi {
}
}
// Push w/ modifications.
- //info("Command: " + ci.getName() + " registration on " + guild.getId() + " completed.");
+ //trace("Command: " + ci.getName() + " registration on " + guild.getId() + " completed.");
try {
cca.queue();
} catch (Exception ex) {
@@ -245,18 +242,15 @@ public class Kiafumi {
}
/*
- Static logger info reference.
+ Static logger references.
*/
public static void info(String str) {
instance.logger.info(str);
}
-
- /*
- Static Logger Error reference.
- */
public static void error(String str) {
instance.logger.error(str);
}
+ public static void debug(String str) { instance.logger.debug(str); }
/**
* Used for logging commands with ease to console via a static method.
@@ -264,15 +258,15 @@ public class Kiafumi {
* @param msg - Any message to append with this.
*/
public static void slashLog(SlashCommandInteractionEvent event, @Nullable String msg) {
- info("User[" + event.getUser().getName() + ":" + event.getUser().getId() + "] RAN " + event.getName() + "." + (msg == null ? "" : msg));
+ info("User [" + event.getUser().getName() + ":" + event.getUser().getId() + "] ran command: \"" + event.getName() + "\"." + (msg == null ? "" : msg));
}
public static void slashLog(SlashCommandInteractionEvent event) {
- info("User[" + event.getUser().getName() + ":" + event.getUser().getId() + "] RAN " + event.getName() + ".");
+ info("User [" + event.getUser().getName() + ":" + event.getUser().getId() + "] ran command: \"" + event.getName() + "\".");
}
public static void slashResponse(SlashCommandInteractionEvent event, String msg) {
- info("User[" + event.getUser().getName() + ":" + event.getUser().getId() + "] CMD RESPONSE: " + msg);
+ info("User [" + event.getUser().getName() + ":" + event.getUser().getId() + "] was provided response: \"" + msg + "\"");
}
// Gets the active database.
diff --git a/src/main/java/moe/oko/Kiafumi/KiafumiConfig.java b/src/main/java/moe/oko/Kiafumi/KiafumiConfig.java
index 4e1607d..1930424 100644
--- a/src/main/java/moe/oko/Kiafumi/KiafumiConfig.java
+++ b/src/main/java/moe/oko/Kiafumi/KiafumiConfig.java
@@ -65,8 +65,7 @@ public class KiafumiConfig {
*/
public boolean load() {
try {
- var n = System.lineSeparator(); // newline
- info("Starting Discord configuration load");
+ var n = System.lineSeparator() + "\033[0m"; // newline
// Discord loaders
var discord = configuration.getConfigurationSection("discord");
@@ -76,12 +75,15 @@ public class KiafumiConfig {
mainGuild = discord.getString("mainGuild");
clientId = discord.getString("clientId");
defaultInvitePermissionLevel = discord.getInt("invitePermissionLevel");
- // Log discord settings.
- info("Discord configuration:" +n+
- "Log Channel: " + logChannel +n+
- "Owner ID: " + ownerId +n+
- "Primary Guild: " + mainGuild +n+
- "Invite link: " + assembleDefaultInvite());
+ // Log discord settings in a neat table.
+ info("Printing loaded discord configuration." +n+
+ "DISCORD CONFIGURATION" +n+
+ "--------------------------------" +n+
+ "Log Channel: \033[0;34m" + logChannel +n+
+ "Owner ID: \033[0;34m" + ownerId +n+
+ "Primary Guild: \033[0;34m" + mainGuild +n+
+ "Invite URL: \033[0;34m" + assembleDefaultInvite() +n+
+ "--------------------------------");
// Kiafumi loaders
var main = configuration.getConfigurationSection("main");
@@ -107,7 +109,6 @@ public class KiafumiConfig {
error("Failed to load configuration!");
return false;
}
- info("Configuration Loaded.");
return true;
}
diff --git a/src/main/java/moe/oko/Kiafumi/command/CommandRegistrar.java b/src/main/java/moe/oko/Kiafumi/command/CommandRegistrar.java
index 1ef49e0..4f74cf2 100644
--- a/src/main/java/moe/oko/Kiafumi/command/CommandRegistrar.java
+++ b/src/main/java/moe/oko/Kiafumi/command/CommandRegistrar.java
@@ -11,6 +11,7 @@ import java.util.stream.Collectors;
import static moe.oko.Kiafumi.Kiafumi.error;
import static moe.oko.Kiafumi.Kiafumi.info;
+import static moe.oko.Kiafumi.Kiafumi.debug;
/**
* CommandRegistrar Class
@@ -49,13 +50,13 @@ public class CommandRegistrar {
// TODO have this check the classpath that we're under and have it scan *that* instead of hard-coding it to only be moe.oko.Kiafumi path.
var classes = findAllClassesContaining("moe.oko.Kiafumi.command");
List commands = new ArrayList<>();
- info("[CommandRegistrar] Discovered " + classes.size() + " classes containing moe.oko.Kiafumi.command in package class.");
+ debug("Discovered " + classes.size() + " classes containing moe.oko.Kiafumi.command in package class.");
for (Class clazz : classes) {
for (Constructor cnstr : clazz.getConstructors()) {
try {
var obj = cnstr.newInstance(); // making an attempt.
if (obj instanceof CommandClass) {
- info("[CommandRegistrar] Registering class " + cnstr.getName());
+ debug("Loading command class %green(" + cnstr.getName() + ").");
commands.add((CommandClass) obj);
}
} catch (InstantiationException ex) {
@@ -63,12 +64,12 @@ public class CommandRegistrar {
}
}
}
- info("[CommandRegistrar] CommandClasses loaded [" + commands.size() + "]");
+ info("Loaded [" + commands.size() + "] command classes.");
return commands;
} catch (IllegalAccessException | InvocationTargetException exception) {
// Now we don't ignore, this is a core issue.
exception.printStackTrace();
- error("[CommandRegistrar] Fatal failure in class loading.");
+ error("Failure in command class loading.");
return null;
}
}
diff --git a/src/main/java/moe/oko/Kiafumi/command/music/MusicCommand.java b/src/main/java/moe/oko/Kiafumi/command/music/MusicCommand.java
index e25800c..be8ac79 100644
--- a/src/main/java/moe/oko/Kiafumi/command/music/MusicCommand.java
+++ b/src/main/java/moe/oko/Kiafumi/command/music/MusicCommand.java
@@ -8,7 +8,6 @@ import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
-import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo;
import moe.oko.Kiafumi.command.CommandClass;
import moe.oko.Kiafumi.model.audio.AudioInfo;
import moe.oko.Kiafumi.model.audio.AudioPlayerSendHandler;
@@ -133,14 +132,16 @@ public class MusicCommand extends CommandClass {
if (info.hasVoted(e.getUser())) {
e.getHook().sendMessage("\u26A0 You've already voted to skip this song!").queue();
} else {
+ // Determine requisite votes.
int votes = info.getSkips();
- int required = Math.round((info.getAuthor().getVoiceState().getChannel().getMembers().size() - 1) / 2); // Determines required amount of votes
- if (votes >= (required)){
+ int channelUsers = info.getAuthor().getVoiceState().getChannel().getMembers().size()-1;
+ int required = channelUsers/2;
+ if (votes+1 >= required){
getPlayer(e.getGuild()).stopTrack();
e.getHook().sendMessage("\u23E9 Skipping current track.").queue();
} else {
info.addSkip(e.getUser());
- e.getHook().sendMessage("**" + e.getUser().getName() + "** voted to skip the track. [" + (votes + 1) + "/" + (required) + "]").queue();
+ e.getHook().sendMessage("**" + e.getUser().getName() + "** voted to skip the track. [" + (votes+1) + "/" + (required) + "]").queue();
}
}
}
@@ -149,7 +150,6 @@ public class MusicCommand extends CommandClass {
slashLog(e);
e.deferReply().queue();
if (isIdle(e.getHook(), e.getGuild())) return;
-
if (isCurrentDj(e.getMember()) || isDj(e.getMember())) {
forceSkipTrack(e.getGuild(), e.getHook());
} else {
@@ -190,7 +190,7 @@ public class MusicCommand extends CommandClass {
case "play":
e.deferReply().queue();
var input = e.getOption("url").getAsString();
- slashLog(e, "INPUT " + input);
+ slashLog(e, " With search \"" + input + "\".");
if(input.contains("https://")) {
loadTrack(input, e.getMember(), e.getHook());
} else {
diff --git a/src/main/java/moe/oko/Kiafumi/command/utility/DuckCommand.java b/src/main/java/moe/oko/Kiafumi/command/utility/DuckCommand.java
index e8203e5..610e66c 100644
--- a/src/main/java/moe/oko/Kiafumi/command/utility/DuckCommand.java
+++ b/src/main/java/moe/oko/Kiafumi/command/utility/DuckCommand.java
@@ -38,7 +38,7 @@ public class DuckCommand extends CommandClass {
if ("search".equals(name)) {
e.deferReply().queue();
String option = e.getOption("query").getAsString();
- slashLog(e, "WITH QUERY " + option);
+ slashLog(e, " With search \"" + option + "\".");
WebSearch ws = WebSearch.instanceOf();
SearchResult sr;
try {
diff --git a/src/main/java/moe/oko/Kiafumi/command/utility/InfoCommand.java b/src/main/java/moe/oko/Kiafumi/command/utility/InfoCommand.java
index d809ef7..604d11a 100644
--- a/src/main/java/moe/oko/Kiafumi/command/utility/InfoCommand.java
+++ b/src/main/java/moe/oko/Kiafumi/command/utility/InfoCommand.java
@@ -38,7 +38,7 @@ public class InfoCommand extends CommandClass {
? e.getMember()
: e.getOption("user").getAsMember();
final var dTF = DateTimeFormatter.ofPattern("MM-dd-yyyy");
- slashLog(e, "FOR USER " + member.getUser().getName() + ":" + member.getId());
+ slashLog(e, " For user [" + member.getUser().getName() + ":" + member.getId() + "].");
// Build embed
EmbedBuilder eb1 = new EmbedBuilder()
.setColor(EmbedUI.INFO)
@@ -56,7 +56,7 @@ public class InfoCommand extends CommandClass {
// Setup variables
final var guild = e.getGuild();
final var dTF2 = DateTimeFormatter.ofPattern("MM-dd-yyyy");
- slashLog(e, "FOR GUILD[" + guild.getId() + ":" + guild.getName() + "]");
+ slashLog(e, " For guild [" + guild.getId() + ":" + guild.getName() + "]");
// Build Embed
EmbedBuilder eb2 = new EmbedBuilder()
.setColor(EmbedUI.INFO)
diff --git a/src/main/java/moe/oko/Kiafumi/command/utility/SettingCommand.java b/src/main/java/moe/oko/Kiafumi/command/utility/SettingCommand.java
index dd2b408..6a5bfa3 100644
--- a/src/main/java/moe/oko/Kiafumi/command/utility/SettingCommand.java
+++ b/src/main/java/moe/oko/Kiafumi/command/utility/SettingCommand.java
@@ -25,7 +25,7 @@ import static moe.oko.Kiafumi.Kiafumi.slashResponse;
public class SettingCommand extends CommandClass {
@Override
public boolean isEnabled() {
- return true; //Another non-disable command
+ return true; // Another non-disable command
}
@Override
@@ -41,7 +41,7 @@ public class SettingCommand extends CommandClass {
case "settings" -> {
slashLog(e);
e.deferReply().queue();
- //No options, just fire an embed off...
+ // No options, just fire an embed off...
EmbedBuilder eb = new EmbedBuilder()
.setColor(EmbedUI.INFO)
.setTitle("Kiafumi Settings")
@@ -49,22 +49,21 @@ public class SettingCommand extends CommandClass {
.setFooter(EmbedUI.BRAND)
.setTimestamp(ZonedDateTime.now());
e.getHook().sendMessageEmbeds(eb.build()).queue();
- return;
}
case "setting" -> {
- //User is attempting a settings modification. Check if admin.
+ // User is attempting a settings modification. Check if admin.
if(!e.getMember().hasPermission(Permission.ADMINISTRATOR) && !e.getMember().isOwner()) {
- slashLog(e, "FAILED PERM CHECK");
+ slashLog(e, EmbedUI.RESPONSE_PRIVILEGES);
e.deferReply(true).queue();
- //Private reply, other people can't see this if ephemeral.
- e.getHook().sendMessage("**You cannot run this command**").queue();
+ // Private reply, other people can't see this if ephemeral.
+ e.getHook().sendMessage("**You cannot run this command.**").queue();
return;
}
switch (e.getSubcommandName().toLowerCase()) {
case "view" -> {
e.deferReply().queue();
String opt = e.getOption("name").getAsString();
- slashLog(e, "SUBCOMMAND[VIEW] FOR " + opt);
+ slashLog(e, "With subcommand \"" + name + "\". Setting \"" + opt + "\".");
EmbedBuilder eb1 = new EmbedBuilder()
.setColor(EmbedUI.INFO)
.setTitle(opt)
@@ -72,13 +71,12 @@ public class SettingCommand extends CommandClass {
.setFooter(EmbedUI.BRAND)
.setTimestamp(ZonedDateTime.now());
e.getHook().sendMessageEmbeds(eb1.build()).queue();
- return;
}
case "set" -> {
e.deferReply().queue();
String opt1 = e.getOption("name").getAsString();
String opt2 = e.getOption("value").getAsString();
- slashLog(e, "SUBCOMMAND[SET] FOR " + opt1 + " TO " + opt2);
+ slashLog(e, "With subcommand \"" + name + "\". Setting \"" + opt1 + "\" to \"" + opt2 + "\".");
String response = server.setOptionByString(opt1, opt2);
slashResponse(e, response);
EmbedBuilder eb2 = new EmbedBuilder()
@@ -88,12 +86,11 @@ public class SettingCommand extends CommandClass {
.setFooter(EmbedUI.BRAND)
.setTimestamp(ZonedDateTime.now());
e.getHook().sendMessageEmbeds(eb2.build()).queue();
- return;
}
case "clear" -> {
e.deferReply().queue();
String opt3 = e.getOption("name").getAsString();
- slashLog(e, "SUBCOMMAND[CLEAR] FOR " + opt3);
+ slashLog(e, "With subcommand \"" + name + "\". Setting \"" + opt3 + "\".");
String response1 = server.resetOptionByString(opt3);
slashResponse(e, response1);
EmbedBuilder eb3 = new EmbedBuilder()
@@ -103,7 +100,6 @@ public class SettingCommand extends CommandClass {
.setFooter(EmbedUI.BRAND)
.setTimestamp(ZonedDateTime.now());
e.getHook().sendMessageEmbeds(eb3.build()).queue();
- return;
}
}
}
@@ -116,7 +112,7 @@ public class SettingCommand extends CommandClass {
List si = new ArrayList<>();
CommandInfo ci2 = new CommandInfo("setting", "Permits modification, viewing, and clearing of settings.", CommandType.COMMAND);
- //For those looking here for inspiration, you CANNOT mix options and subcommands. You can only have one or the other.
+ // For those looking here for inspiration, you CANNOT mix options and subcommands. You can only have one or the other.
CommandInfo ci = new CommandInfo("view", "Shows the current value for the setting provided.", CommandType.SUBCOMMAND);
ci.addOption("name", "The name of the setting to display", OptionType.STRING, true);
diff --git a/src/main/java/moe/oko/Kiafumi/listener/MainListener.java b/src/main/java/moe/oko/Kiafumi/listener/MainListener.java
index 3f03d6c..a82d9de 100644
--- a/src/main/java/moe/oko/Kiafumi/listener/MainListener.java
+++ b/src/main/java/moe/oko/Kiafumi/listener/MainListener.java
@@ -46,8 +46,12 @@ public class MainListener extends ListenerAdapter {
*/
@Override
public void onReady(@NotNull ReadyEvent event) {
- info("Received READY signal from Discord, bot is now logged in." + System.lineSeparator() +
- " Guilds Active: " + event.getGuildAvailableCount() + " Guilds Unavailable: " + event.getGuildUnavailableCount());
+ var n = System.lineSeparator();
+ info("Received READY signal from Discord, bot is now logged in." +n+
+ "--------------------------------" +n+
+ "Active Guilds: " + event.getGuildAvailableCount() +n+
+ "Guilds Unavailable: " + event.getGuildUnavailableCount() +n+
+ "--------------------------------");
}
/**
diff --git a/src/main/java/moe/oko/Kiafumi/model/KiafumiDB.java b/src/main/java/moe/oko/Kiafumi/model/KiafumiDB.java
index 28006b7..021df99 100644
--- a/src/main/java/moe/oko/Kiafumi/model/KiafumiDB.java
+++ b/src/main/java/moe/oko/Kiafumi/model/KiafumiDB.java
@@ -8,8 +8,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import static moe.oko.Kiafumi.Kiafumi.error;
-import static moe.oko.Kiafumi.Kiafumi.info;
+import static moe.oko.Kiafumi.Kiafumi.*;
/**
* Kiafumi DB Class
@@ -126,7 +125,7 @@ public class KiafumiDB {
}
String modRole = rs.getString(6);
Server server = new Server(id, welcomeEnabled, welcomeChannel, joinRole, protectionEnabled, modRole);
- info("Loaded: " + server);
+ debug("Loaded " + server + "from database.");
servers.add(server);
}
return servers;
diff --git a/src/main/java/moe/oko/Kiafumi/model/ServerManager.java b/src/main/java/moe/oko/Kiafumi/model/ServerManager.java
index 1a04f37..b12a9bd 100644
--- a/src/main/java/moe/oko/Kiafumi/model/ServerManager.java
+++ b/src/main/java/moe/oko/Kiafumi/model/ServerManager.java
@@ -7,8 +7,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.List;
-import static moe.oko.Kiafumi.Kiafumi.error;
-import static moe.oko.Kiafumi.Kiafumi.info;
+import static moe.oko.Kiafumi.Kiafumi.*;
/**
* ServerManager Class
@@ -30,7 +29,6 @@ public class ServerManager {
}
HashMap serverHashMap = new HashMap<>();
for(Server s : loadedServers) {
- info("Loading " + s + " into memory from db.");
serverHashMap.put(s.getId(), s);
}
info("Successfully loaded " + serverHashMap.size() + " servers.");
@@ -63,16 +61,15 @@ public class ServerManager {
* @return - whether the function succeeded.
*/
public boolean createNewDefaultServer(Guild guild) {
- info("Started default server creation for server " + guild.getId());
+ var serverName = guild.getName() + ":" + guild.getId() + "].";
+ debug("Creating data for [" + serverName);
Server server = new Server(guild.getId());
- if(Kiafumi.instance.getDatabase().createServerInformation(guild)) {
- info("New defaults persistent for " + server);
- servers.put(server.getId(), server);
- return true;
- } else {
+ if(!Kiafumi.instance.getDatabase().createServerInformation(guild)) {
error("Failed to create new defaults for " + guild.getId());
return false;
}
+ servers.put(server.getId(), server);
+ return true;
}
/**
diff --git a/src/main/java/moe/oko/Kiafumi/util/EmbedUI.java b/src/main/java/moe/oko/Kiafumi/util/EmbedUI.java
index 9d50d99..ee1a997 100644
--- a/src/main/java/moe/oko/Kiafumi/util/EmbedUI.java
+++ b/src/main/java/moe/oko/Kiafumi/util/EmbedUI.java
@@ -7,6 +7,7 @@ import java.awt.Color;
* @author oko
*/
public abstract class EmbedUI {
+ // TODO: restructure & rename class - it has surpassed its scope.
/**
* Shorthand reference for common EmbedBuilder colors & strings.
* I chose these colors based on the Pantone Color of the year.
@@ -14,6 +15,7 @@ public abstract class EmbedUI {
// Strings
public static final String BRAND = "Kiafumi - oko.moe";
+ public static final String RESPONSE_PRIVILEGES = " Insufficient privileges.";
// Colors
public static final Color SUCCESS = new Color(136,176,75);
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index ee78c8d..dbf28ce 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -10,7 +10,7 @@
#DISCORD CONFIG STACK
discord:
#Paste in your bot token here.
- token: "DO NOT SHARE THIS"
+ token: "DO NOT SHARE"
#The main guild the bot will recognize and do protection actions on. (Use LossPrevention for more in-depth actions!)
mainGuild: ""
#The channel ID the bot will send important logging messages to.
@@ -19,8 +19,9 @@ discord:
ownerId: ""
#The client ID of the bot (for invite generation)
clientId: ""
- #Level of permissions for the invite (If you don't know this, use https://discordapi.com/permissions.html) (ADMINISTRATOR is default)
- invitePermissionLevel: 8
+ #Level of permissions for the invite (If you don't know this, use https://discordapi.com/permissions.html)
+ #If problems occur, you can use 8 (Administrator)
+ invitePermissionLevel: 139855252544
#MAIN CONFIG STACK
main:
#Currently, unimplemented, maybe in the future if performance becomes and issue.
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..6d9d590
--- /dev/null
+++ b/src/main/resources/log4j2.xml
@@ -0,0 +1,18 @@
+
+
+
+ %d{HH:mm} %highlight{%-5level} %cyan{%logger{7}} - %m%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file