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

com.ps.s4l.service.Splunk4LogbackService Maven / Gradle / Ivy

The newest version!
package com.ps.s4l.service;

import ch.qos.logback.classic.Level;
import com.ps.s4l.model.LoggingDetail;
import com.splunk.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.*;


public class Splunk4LogbackService implements LoggingDetailService{

    Logger logger = LoggerFactory.getLogger(Splunk4LogbackService.class);


    /**
     * Apps to monitor, default * means all
     */
    private String appId = "*";


    /**
     * Default to poll every minute
     */
    private long delay = 60000;

    /**
     * Control switch to stop or start the monitoring.
     */
    private boolean run = true;

    /**
     * The splunk service interface
     */
    private Service service;

    /**
     * Constructor to set all the available options
     * @param host splunk hostname
     * @param username splunk username
     * @param password splunk password
     * @param appId when you have multiple apps accessing the splunk collection, you can specify individual apps.
     * @param delay (in ms) how often should a check be run and logging levels set.
     */
    public Splunk4LogbackService(String host, int port, String username, String password, String appId, Long delay) {
        if(appId != null) {
            this.appId = appId;
        }
        if(delay != null && delay >= 60000) {//not sure why you would want this faster than a minute.
            this.delay = delay;
        }else if(delay != null && delay < 60000){
            String noBueno = "You're trying to set logging details checks too often.  Should be >= 1 min.";
            logger.error(noBueno);
            throw new RuntimeException(noBueno);
        }

        // Create a map of arguments and add login parameters
        ServiceArgs loginArgs = new ServiceArgs();
        loginArgs.setUsername(username);
        loginArgs.setPassword(password);
        loginArgs.setHost(host);
        loginArgs.setPort(port);

        service = Service.connect(loginArgs);
        logger.info("connected to splunk host={}", host);

        //make sure we have Splunk4logback installed before we run
        for (Application app : service.getApplications().values()) {
            if("splunk4logback".equals(app.getName().toLowerCase())){
                logger.info("Splunk4Logback is installed going to run now.");
                run();
            }
        }
    }

    /**
     * need to have the user set some data.
     */
    private Splunk4LogbackService() {}

    @Override
    public Collection findAll() {
        logger.debug("finding all our logging details from splunk");

        ResponseMessage msg =
                service.get("/servicesNS/nobody/splunk4logback/storage/collections/data/splunk4logback");

        Set loggingDetails = new HashSet<>();

        try {
            ResultsReaderJson levels = new ResultsReaderJson(msg.getContent());

            for (Iterator iter = levels.iterator(); iter.hasNext(); ) {
                Event element = iter.next();

                LoggingDetail detail =
                        new LoggingDetail(element.get("_key"),
                        element.get("AppID"),element.get("Logger"),element.get("Level"));
                loggingDetails.add(detail);
            }

        }catch(IOException e){
            logger.error("ummm couldn't read the response", e);
        }

        logger.debug("found {} logging details.", loggingDetails.size());
        return loggingDetails;
    }

    @Override
    public Collection findByAppId(String appId) {
        logger.debug("finding logging details for {} from splunk", appId);

        ResponseMessage msg =
                service.get("/servicesNS/nobody/splunk4logback/storage/collections/data/splunk4logback");

        Set loggingDetails = new HashSet<>();

        try {
            ResultsReaderJson levels = new ResultsReaderJson(msg.getContent());

            for (Iterator iter = levels.iterator(); iter.hasNext(); ) {
                Event element = iter.next();
                if(element.get("AppID").equals(appId)) {
                    LoggingDetail detail =
                            new LoggingDetail(element.get("_key"),
                                    element.get("AppID"), element.get("Logger"), element.get("Level"));
                    loggingDetails.add(detail);
                }
            }

        }catch(IOException e){
            logger.error("ummm couldn't read the response", e);
        }

        logger.debug("found {} logging details.", loggingDetails.size());
        return loggingDetails;
    }

    @Override
    public LoggingDetail save(LoggingDetail loggingDetail) {
        throw new UnsupportedOperationException("sorry, it's not supported yet.");
    }

    @Override
    public void stop() {
        logger.debug("Splunk4Logback is stopping.");
        run = false;
    }

    @Override
    public void restart() {
        logger.debug("Splunk4Logback is restarting.");
        run = true;
    }

    @Override
    public boolean isRunning() {
        return run;
    }

    private void run() {

        while(run) {
            logger.info("Splunk4Logback is running.");

            Collection loggingDetails = Collections.emptyList();

            if ("*".equals(appId)) {
                loggingDetails = findAll();
            } else {
                loggingDetails = findByAppId(appId);
            }

            for (LoggingDetail loggingDetail : loggingDetails) {
                ch.qos.logback.classic.Logger classicLogger =
                        (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(loggingDetail.getLogger());

                String level = loggingDetail.getLevel() == null ? "SKIP" : loggingDetail.getLevel().toUpperCase();

                switch (level) {
                    case "SKIP":
                        break;
                    case "TRACE":
                        logger.debug("set logging level for {} to TRACE on AppId {}",
                                loggingDetail.getLogger(),
                                loggingDetail.getAppId());
                        classicLogger.setLevel(Level.TRACE);
                        break;
                    case "DEBUG":
                        logger.debug("set logging level for {} to DEBUG on AppId {}",
                                loggingDetail.getLogger(),
                                loggingDetail.getAppId());
                        classicLogger.setLevel(Level.DEBUG);
                        break;
                    case "INFO":
                        logger.debug("set logging level for {} to INFO on AppId {}",
                                loggingDetail.getLogger(),
                                loggingDetail.getAppId());
                        classicLogger.setLevel(Level.INFO);
                        break;
                    case "WARN":
                        logger.debug("set logging level for {} to WARN on AppId {}",
                                loggingDetail.getLogger(),
                                loggingDetail.getAppId());
                        classicLogger.setLevel(Level.WARN);
                        break;
                    case "ERROR":
                        logger.debug("set logging level for {} to ERROR on AppId {}",
                                loggingDetail.getLogger(),
                                loggingDetail.getAppId());
                        classicLogger.setLevel(Level.ERROR);
                        break;
                    default:
                        break;
                }

            }

            try {
                Thread.sleep(delay);
            } catch (InterruptedException e) {
                logger.error("we got interrupted trying to sleep for our next run", e);
            }
        }

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy