com.addthis.hydra.job.spawn.SpawnFormattedLogger.java Source code

Java tutorial

Introduction

Here is the source code for com.addthis.hydra.job.spawn.SpawnFormattedLogger.java

Source

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.addthis.hydra.job.spawn;

import javax.annotation.Nullable;

import java.io.File;

import java.util.Map;

import com.addthis.basis.util.JitterClock;
import com.addthis.basis.util.Parameter;

import com.addthis.bundle.core.Bundle;
import com.addthis.bundle.core.BundleFormat;
import com.addthis.bundle.value.ValueArray;
import com.addthis.bundle.value.ValueFactory;
import com.addthis.hydra.job.Job;
import com.addthis.hydra.job.JobTask;
import com.addthis.hydra.task.output.DataOutputFile;
import com.addthis.hydra.task.output.DataOutputTypeList;
import com.addthis.hydra.task.output.DefaultOutputWrapperFactory;
import com.addthis.hydra.task.output.OutputStreamChannel;
import com.addthis.hydra.task.output.OutputWrapperFactory;
import com.addthis.hydra.task.output.OutputWriter;

import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SpawnFormattedLogger {

    public enum EventType {
        JOB_FINISH, SPAWN_STATE
    }

    private static final Logger log = LoggerFactory.getLogger(SpawnFormattedLogger.class);
    private static final String clusterName = Parameter.value("cluster.name", "localhost");
    public static final String[] LOG_PATH = { "{{DATE_YEAR}}", "/", "{{DATE_MONTH}}", "/", "{{DATE_DAY}}", "/",
            "{{FILE_PREFIX_HOUR}}" };

    @Nullable
    private final DataOutputTypeList bundleLog;

    private SpawnFormattedLogger() {
        log.info("Creating the null-based spawn formatted logger - no output emitted.");
        bundleLog = null;
    }

    private SpawnFormattedLogger(File file) {
        log.info("Creating the file-based spawn formatted logger.");
        DataOutputTypeList newOutputSink = null;
        try {
            String absPath = file.getAbsolutePath();
            OutputWrapperFactory factory = new DefaultOutputWrapperFactory(absPath);
            OutputWriter writer = new OutputWriter();
            writer.setMaxOpen(1).setOutputWrapperFactory(factory).setFormat(new OutputStreamChannel());
            newOutputSink = new DataOutputFile().setWriter(writer).setPath(LOG_PATH);
            newOutputSink.init();
        } catch (Exception ex) {
            log.error("", ex);
        } finally {
            bundleLog = newOutputSink;
        }
    }

    static SpawnFormattedLogger createFileBasedLogger(File file) {
        return new SpawnFormattedLogger(file);
    }

    static SpawnFormattedLogger createNullLogger() {
        return new SpawnFormattedLogger();
    }

    private void bundleSetValue(Bundle bundle, String field, String value) {
        BundleFormat format = bundleLog.getFormat();
        bundle.setValue(format.getField(field), ValueFactory.create(value));
    }

    private void bundleSetValue(Bundle bundle, String field, int value) {
        BundleFormat format = bundleLog.getFormat();
        bundle.setValue(format.getField(field), ValueFactory.create(value));
    }

    private void bundleSetValue(Bundle bundle, String field, long value) {
        BundleFormat format = bundleLog.getFormat();
        bundle.setValue(format.getField(field), ValueFactory.create(value));
    }

    private void bundleSetValue(Bundle bundle, String field, boolean value) {
        BundleFormat format = bundleLog.getFormat();
        bundle.setValue(format.getField(field), ValueFactory.create(value ? 1 : 0));
    }

    private Bundle initBundle(EventType event) {
        assert (bundleLog != null);
        Bundle bundle = bundleLog.createBundle();
        bundleSetValue(bundle, "CLUSTER", clusterName);
        bundleSetValue(bundle, "EVENT_TYPE", event.toString());
        long time = JitterClock.globalTime();
        DateTime dateTime = new DateTime(time);
        bundleSetValue(bundle, "TIME", time);
        bundleSetValue(bundle, "DATE_YEAR", dateTime.getYear());
        bundleSetValue(bundle, "DATE_MONTH", dateTime.getMonthOfYear());
        bundleSetValue(bundle, "DATE_DAY", dateTime.getDayOfMonth());
        bundleSetValue(bundle, "FILE_PREFIX_HOUR", "logger-" + String.format("%02d", dateTime.getHourOfDay()));
        return bundle;
    }

    /**
     * Emit to the output periodic statistics about the cluster that are collected by Spawn.
     */
    void periodicState(Map<String, Long> events) {
        if (bundleLog != null) {
            try {
                Bundle bundle = initBundle(EventType.SPAWN_STATE);
                for (Map.Entry<String, Long> entry : events.entrySet()) {
                    bundleSetValue(bundle, entry.getKey().toUpperCase(), entry.getValue());
                }
                bundleLog.send(bundle);
            } catch (Exception ex) {
                log.error("", ex);
            }
        }
    }

    /**
     * Emit to the output sink information about the completion of a job.
     */
    void finishJob(Job job) {
        if (bundleLog != null) {
            try {
                Bundle bundle = initBundle(EventType.JOB_FINISH);
                BundleFormat format = bundleLog.getFormat();
                bundleSetValue(bundle, "JOB_ID", job.getId());
                bundleSetValue(bundle, "JOB_STATE", job.getState().toString());
                bundleSetValue(bundle, "JOB_WAS_STOPPED", job.getWasStopped());
                Long start = job.getStartTime();
                Long end = job.getEndTime();
                if (start != null) {
                    bundleSetValue(bundle, "JOB_START_TIME", start);
                }
                if (end != null) {
                    bundleSetValue(bundle, "JOB_END_TIME", end);
                }
                if (start != null && end != null) {
                    bundleSetValue(bundle, "JOB_ELAPSED_TIME", end - start);
                }
                int taskCount = job.getTaskCount();
                bundleSetValue(bundle, "JOB_TASK_COUNT", taskCount);
                ValueArray taskMeanRates = ValueFactory.createArray(taskCount);
                for (int i = 0; i < taskCount; i++) {
                    JobTask task = job.getTask(i);
                    taskMeanRates.add(ValueFactory.create(task.getMeanRate()));
                }
                bundle.setValue(format.getField("TASK_AVG_RATES"), taskMeanRates);
                bundleLog.send(bundle);
            } catch (Exception ex) {
                log.error("", ex);
            }
        }
    }

    void close() {
        if (bundleLog != null) {
            bundleLog.sendComplete();
        }
    }

}