Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#83 #101

Merged
merged 6 commits into from
Feb 18, 2024
Merged

#83 #101

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions src/urChatBasic/backend/logging/URLogger.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URISyntaxException;
import java.util.Map;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.LoggerContext;
Expand Down Expand Up @@ -34,10 +35,15 @@ public static void init () throws IOException, URISyntaxException
logDir.mkdir();
}

System.setProperty("log4j2.configurationFile", DriverGUI.class.getResource(LOG4J_CONFIG_FILE).toURI().toString());
File logConfigFile = new File(DriverGUI.class.getResource(LOG4J_CONFIG_FILE).toURI());

if(!logConfigFile.exists())
throw new IOException("LOG FILE NOT FOUND");

// System.setProperty("log4j2.debug", "true");
System.setProperty("log4j2.configurationFile", logConfigFile.toString());

LOGGER = LoggerFactory.getLogger(URLogger.class);
LOGGER = LoggerFactory.getLogger("urchat");

Logger testLog = getLogger(LOGGER.getName(), Logger.class);

Expand Down Expand Up @@ -84,6 +90,30 @@ public static Marker getMarker (String markerName)
// }
// }

/**
* Get the path for the logfile associated with the given markerName.
*
* @param markerName The markerName associated with the logfile.
* @return The path for the associated logfile, or null if not found.
*/
public static String getLogFilePath(String markerName) {
// Get the root LoggerConfig
Configuration rootLoggerConfig = currentConfig;
if (rootLoggerConfig != null) {
// Find the appender associated with the given markerName
Map<String, Appender> appenders = rootLoggerConfig.getAppenders();
String appenderName = markerName + "Appender";
Appender appender = appenders.get(appenderName);
if (appender instanceof FileAppender) {
// If the appender is a FileAppender, return its file name
FileAppender fileAppender = (FileAppender) appender;
return fileAppender.getFileName();
}
}
// Return null if the logfile for the given markerName is not found
return null;
}

public static void logChannelComms (IRCChannelBase ircChannel, String message)
{

Expand Down
177 changes: 177 additions & 0 deletions src/urChatBasic/backend/utils/LogPatternParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package urChatBasic.backend.utils;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LogPatternParser
{

// Define enum for log patterns
public enum LogPattern
{
DATE("%d", "(?<DATE>.*UTC?)", Date.class, "UTC "),
SERVER("%marker", "\\s(?<SERVER>[A-Za-z0-9.-]+)-", String.class, "-"),
CHANNEL("%marker", "(?<CHANNEL>#.*?)\\s", String.class, " "), // Named group for channel, excluding the trailing whitespace
USER("%msg", "(?<USER>.*?):", String.class, ": "),
MESSAGE("%msg", "\\s(?<MESSAGE>.*)$", String.class, "");

private final String pattern;
private final String regex;
private final String appendString;
private final Class<?> patternClass;
public final static String PATTERN_LAYOUT = "%d{yyy-MM-dd HH:mm:ss.SSS}{UTC}UTC %marker %msg%n";
public final static String DATE_LAYOUT = "yyyy-MM-dd HH:mm:ss.SSS";

LogPattern (String pattern, String regex, Class<?> patternClass, String appendString)
{
this.pattern = pattern;
this.regex = regex;
this.patternClass = patternClass;
this.appendString = appendString;
}

public String getPattern ()
{
return pattern;
}

public Class<?> getPatternClass ()
{
return patternClass;
}

public String getRegex ()
{
return regex;
}

public String getMatchGroup ()
{
return this.toString();
}

public String getAppendString ()
{
return appendString;
}
}

public static Date parseDate (String dateString)
{
dateString = dateString.trim();
// Step 1: Define the DateTimeFormatter with the pattern
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
TemporalAccessor temporalAccessor = null;
try{
// Step 2: Parse the string into a TemporalAccessor object using the formatter
temporalAccessor = formatter.parse(dateString.replace("UTC", ""));
} catch (Exception exc)
{
System.out.println(exc);
}

// Step 3: Convert the TemporalAccessor to a LocalDateTime object
LocalDateTime localDateTime = LocalDateTime.from(temporalAccessor);

// Step 4: Convert the LocalDateTime to the local timezone
LocalDateTime localDateTimeInLocalTimeZone = localDateTime
.atZone(ZoneId.of("UTC"))
.withZoneSameInstant(ZoneId.systemDefault())
.toLocalDateTime();

// Step 5: Convert the LocalDateTime to a Date object
Date date = Date.from(localDateTimeInLocalTimeZone.atZone(ZoneId.systemDefault()).toInstant());


return date;
}

// Method to format Date object to string in UTC
public static String formatDateToString(Date date) {
// Define the DateTimeFormatter with the pattern
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

// Convert the Date object to LocalDateTime
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();

// Convert the LocalDateTime to UTC time zone
LocalDateTime localDateTimeInUtc = localDateTime.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime();

// Format the LocalDateTime to string
return formatter.format(localDateTimeInUtc);
}

// Parse log line using specified pattern
public static void parseLogLine (String logLine)
{
Map<String, Object> parsedValues = new HashMap<String, Object>();

for (LogPattern pattern : LogPattern.values())
{
Pattern regexPattern = Pattern.compile(pattern.getRegex());
Matcher matcher = regexPattern.matcher(logLine);
if (matcher.find())
{
String fullMatch = matcher.group(0);
String match = matcher.group(pattern.getMatchGroup());
System.out.println(pattern.name() + " group: " + match);
// parsedValues.put(pattern.toString(), match);
switch (pattern.getPatternClass().getSimpleName()) {
case "Date":
parsedValues.put(pattern.toString(), parseDate(match));
logLine = logLine.replaceFirst(fullMatch, "").trim();
break;
default:
parsedValues.put(pattern.toString(), match);
if(logLine.length() == fullMatch.length())
break;

logLine = logLine.replaceFirst(fullMatch, "").trim();
break;
}
}
}

System.out.println("Done");
}

public static Map<String, Object> parseLogLineFull (String logLine) {
logLine = logLine.trim();
Map<String, Object> parsedValues = new HashMap<>();

StringBuilder combinedRegexBuilder = new StringBuilder();
combinedRegexBuilder.append(LogPattern.DATE.getRegex());
combinedRegexBuilder.append(LogPattern.SERVER.getRegex());
combinedRegexBuilder.append(LogPattern.CHANNEL.getRegex());
combinedRegexBuilder.append(LogPattern.USER.getRegex());
combinedRegexBuilder.append(LogPattern.MESSAGE.getRegex());
String combinedRegex = combinedRegexBuilder.toString();

Pattern regexPattern = Pattern.compile(combinedRegex);
Matcher matcher = regexPattern.matcher(logLine);
while (matcher.find()) {
for (LogPattern pattern : LogPattern.values()) {
if (matcher.group(pattern.toString()) != null) {
String match = matcher.group(pattern.getMatchGroup());
switch (pattern.getPatternClass().getSimpleName()) {
case "Date":
parsedValues.put(pattern.toString(), parseDate(match));
break;
default:
parsedValues.put(pattern.toString(), match);
break;
}
}
}
}

return parsedValues;
}
}
101 changes: 101 additions & 0 deletions src/urChatBasic/backend/utils/ReverseLineInputStream.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package urChatBasic.backend.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;

/**
* @see https://web.archive.org/web/20220701011119/https://stackoverflow.com/questions/8664705/how-to-read-file-from-end-to-start-in-reverse-order-in-javaa
*/
public class ReverseLineInputStream extends InputStream {

RandomAccessFile in;

long currentLineStart = -1;
long currentLineEnd = -1;
long currentPos = -1;
long lastPosInFile = -1;
int lastChar = -1;


public ReverseLineInputStream(File file) throws FileNotFoundException {
in = new RandomAccessFile(file, "r");
currentLineStart = file.length();
currentLineEnd = file.length();
lastPosInFile = file.length() -1;
currentPos = currentLineEnd;

}

private void findPrevLine() throws IOException {
if (lastChar == -1) {
in.seek(lastPosInFile);
lastChar = in.readByte();
}

currentLineEnd = currentLineStart;

// There are no more lines, since we are at the beginning of the file and no lines.
if (currentLineEnd == 0) {
currentLineEnd = -1;
currentLineStart = -1;
currentPos = -1;
return;
}

long filePointer = currentLineStart -1;

while ( true) {
filePointer--;

// we are at start of file so this is the first line in the file.
if (filePointer < 0) {
break;
}

in.seek(filePointer);
int readByte = in.readByte();

// We ignore last LF in file. search back to find the previous LF.
if (readByte == 0xA && filePointer != lastPosInFile ) {
break;
}
}
// we want to start at pointer +1 so we are after the LF we found or at 0 the start of the file.
currentLineStart = filePointer + 1;
currentPos = currentLineStart;
}

public int read() throws IOException {

if (currentPos < currentLineEnd ) {
in.seek(currentPos++);
int readByte = in.readByte();
return readByte;
} else if (currentPos > lastPosInFile && currentLineStart < currentLineEnd) {
// last line in file (first returned)
findPrevLine();
if (lastChar != '\n' && lastChar != '\r') {
// last line is not terminated
return '\n';
} else {
return read();
}
} else if (currentPos < 0) {
return -1;
} else {
findPrevLine();
return read();
}
}

@Override
public void close() throws IOException {
if (in != null) {
in.close();
in = null;
}
}
}
2 changes: 1 addition & 1 deletion src/urChatBasic/backend/utils/URPreferencesUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ else if (URProfilesUtil.getActiveProfilePath().nodeExists(styleName))

} catch (Exception e)
{
Constants.LOGGER.error("Active Profile: ["+URProfilesUtil.getActiveProfileName()+"] Unable to load ["+loadedStyle.getAttribute("name")+"]"+ " attempted with path: " + stylePrefPath);
Constants.LOGGER.error("Active Profile: ["+URProfilesUtil.getActiveProfileName()+"] Unable to load ["+loadedStyle.getAttribute("name")+"]"+ " attempted with path: " + stylePrefPath, e);
return targetStyle;
}

Expand Down
27 changes: 16 additions & 11 deletions src/urChatBasic/backend/utils/URProfilesUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,17 @@ public static String[] getProfiles ()
return profileNames;
}


public static void deleteProfile (String profileName)
{
deleteProfile(profileName, true);
}

public static void deleteProfile (String profileName, boolean fireListeners)
{
try
{
String[] allProfiles = getProfiles();

if(allProfiles.length > 1)
{
Constants.LOGGER.info( "Deleting profile [" + profileName + "].");
Constants.BASE_PREFS.node(profileName).removeNode();
fireListeners(EventType.DELETE);
}
else
throw new BackingStoreException("Unable to delete the last profile.");

if(profileName.equals(getActiveProfileName()))
{
if(profileExists(getDefaultProfile()))
Expand All @@ -85,6 +80,16 @@ public static void deleteProfile (String profileName)
}
}

if(allProfiles.length > 1)
{
Constants.LOGGER.info( "Deleting profile [" + profileName + "].");
Constants.BASE_PREFS.node(profileName).removeNode();
if(fireListeners)
fireListeners(EventType.DELETE);
}
else
throw new BackingStoreException("Unable to delete the last profile.");

} catch (BackingStoreException e)
{
Constants.LOGGER.error("Problem deleting profile [" + profileName +"]." + e.getLocalizedMessage());
Expand All @@ -96,7 +101,7 @@ public static void deleteProfile (String profileName)
*/
public static void deleteProfile ()
{
deleteProfile(getActiveProfileName());
deleteProfile(getActiveProfileName(), true);
}

public static String getActiveProfileName ()
Expand Down
Loading
Loading