io.convergence_platform.services.observability.ServiceLogFileWriter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of service-lib Show documentation
Show all versions of service-lib Show documentation
Holds the common functionality needed by all Convergence Platform-based services written in Java.
The newest version!
package io.convergence_platform.services.observability;
import org.yaml.snakeyaml.Yaml;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Map;
import java.util.TimeZone;
public class ServiceLogFileWriter {
private final static String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS zzz";
private final static TimeZone UTC = TimeZone.getTimeZone("UTC");
private final static SimpleDateFormat ISO_DATE_FORMATTER_UTC = new SimpleDateFormat(ISO_FORMAT);
private final static DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(ISO_FORMAT);
private String fileNamePattern = null;
private String logFolder = null;
private FileOutputStream output;
private long validUntil = 0;
static {
ISO_DATE_FORMATTER_UTC.setTimeZone(UTC);
}
public ServiceLogFileWriter() {
initializeProfile();
initializeLogFile(System.currentTimeMillis());
}
private void initializeProfile() {
LogConfig config = new LogConfig();
String profile = System.getProperty("spring.profiles.active");
getLogConfig(config, profile);
if (config.incomplete())
getLogConfig(config, null);
if (config.incomplete())
throw new RuntimeException("Invalid service configuration. Can't initialize stdout/stderr redirection to file.");
fileNamePattern = config.filePattern;
logFolder = config.folder;
if (!logFolder.endsWith("/")) {
logFolder = logFolder + "/";
}
}
private void getLogConfig(LogConfig config, String profile) {
if (profile == null) {
profile = "";
} else {
profile = "-" + profile;
}
String path = "application" + profile + ".yaml";
try {
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(path);
Yaml yaml = new Yaml();
Map configuration = yaml.load(inputStream);
configuration = (Map) configuration.get("observability");
if (config.filePattern == null && configuration.containsKey("stdout")) {
config.filePattern = (String) configuration.get("stdout");
}
if (config.folder == null && configuration.containsKey("path")) {
config.folder = (String) configuration.get("path");
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void initializeLogFile(long time) {
if (this.output != null) {
try {
output.flush();
} catch (IOException ex) {
ex.printStackTrace();
}
}
Date date = new Date(time);
String originalUtcIsoDate = ISO_DATE_FORMATTER_UTC.format(date);
String utcIsoDate = originalUtcIsoDate.substring(0, 15) + "0:00.000 UTC";
String filePostfix = (originalUtcIsoDate.substring(0, 15) + "0")
.replace(" ", "")
.replace(":", "")
.replace("T", "")
.replace("-", "");
ZonedDateTime zonedDateTime = ZonedDateTime.parse(utcIsoDate, DATE_TIME_FORMATTER);
long epochMilliSeconds = zonedDateTime.toInstant().toEpochMilli();
validUntil = epochMilliSeconds + 10 * 60 * 1000; // + 10 minutes
try {
String path = logFolder + fileNamePattern.replace("{TIME}", filePostfix);
this.output = new FileOutputStream(path, true);
this.output.write(("------------------------------------------------------------\n" +
"Language: Java\nFormat: Spring Boot\n" +
"------------------------------------------------------------" +
"\n\n\n").getBytes());
} catch (Exception ex) {
ex.printStackTrace();
}
}
public synchronized void write(int b) {
try {
FileOutputStream outputStream = getOutput();
outputStream.write(b);
outputStream.flush();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public synchronized void write(byte[] buf) throws IOException {
getOutput().write(buf);
}
public synchronized void write(byte[] buf, int off, int len) {
try {
FileOutputStream outputStream = getOutput();
outputStream.write(buf, off, len);
outputStream.flush();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public synchronized void flush() {
try {
getOutput().flush();
} catch (IOException ex) {
ex.printStackTrace();
}
}
private FileOutputStream getOutput() {
long time = System.currentTimeMillis();
if (time > validUntil) {
initializeLogFile(time);
}
return output;
}
}
class LogConfig {
public String folder;
public String filePattern;
public boolean incomplete() {
return folder == null || filePattern == null;
}
}