All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.convergence_platform.services.observability.ServiceLogFileWriter Maven / Gradle / Ivy

Go to download

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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy