com.jkoolcloud.jesl.tnt4j.sink.JKCloudEventSink.java Source code

Java tutorial

Introduction

Here is the source code for com.jkoolcloud.jesl.tnt4j.sink.JKCloudEventSink.java

Source

/*
 * Copyright 2015 JKOOL, LLC.
 *
 * 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.jkoolcloud.jesl.tnt4j.sink;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.lang3.StringUtils;

import com.jkoolcloud.jesl.net.JKClient;
import com.jkoolcloud.tnt4j.core.KeyValueStats;
import com.jkoolcloud.tnt4j.core.OpLevel;
import com.jkoolcloud.tnt4j.core.Snapshot;
import com.jkoolcloud.tnt4j.format.EventFormatter;
import com.jkoolcloud.tnt4j.sink.AbstractEventSink;
import com.jkoolcloud.tnt4j.sink.DefaultEventSinkFactory;
import com.jkoolcloud.tnt4j.sink.EventSink;
import com.jkoolcloud.tnt4j.source.Source;
import com.jkoolcloud.tnt4j.tracker.TrackingActivity;
import com.jkoolcloud.tnt4j.tracker.TrackingEvent;
import com.jkoolcloud.tnt4j.utils.Utils;

/**
 * <p>
 * This class implements <code>EventSink</code> with HTTP/S as the underlying sink implementation.
 * </p>
 *
 *
 * @version $Revision: 7 $
 *
 * @see TrackingActivity
 * @see TrackingEvent
 * @see OpLevel
 * @see EventSink
 * @see EventFormatter
 */
public class JKCloudEventSink extends AbstractEventSink {
    private static final EventSink logger = DefaultEventSinkFactory.defaultEventSink(JKCloudEventSink.class);

    public static final String KEY_SENT_BYTES = "sink-sent-bytes";
    public static final String KEY_LAST_BYTES = "sink-last-bytes";
    public static final String KEY_SENT_MSGS = "sink-sent-messages";
    public static final String KEY_SERVICE_URL = "sink-service-url";

    private EventSink logSink;
    private JKClient jkHandle;

    private String url = "localhost";
    private String proxyHost;
    private String accessToken;
    private int proxyPort = 0;
    private AtomicLong sentBytes = new AtomicLong(0);
    private AtomicLong lastBytes = new AtomicLong(0);
    private AtomicLong sentMsgs = new AtomicLong(0);

    /**
     * Create a socket event sink based on a given URL and formatter. Another sink can be associated with this sink
     * where all events are routed.
     *
     * @param name
     *            sink name
     * @param url
     *            http/https URL to jkool cloud service
     * @param frm
     *            event formatter associated with this sink
     * @param sink
     *            piped sink where all events are piped
     *
     */
    public JKCloudEventSink(String name, String url, EventFormatter frm, EventSink sink) {
        this(name, url, null, frm, sink);
    }

    /**
     * Create a socket event sink based on a given URL and formatter. Another sink can be associated with this sink
     * where all events are routed.
     *
     * @param name
     *            sink name
     * @param url
     *            http/https URL to jkool cloud service
     * @param token
     *            api access token
     * @param frm
     *            event formatter associated with this sink
     * @param sink
     *            piped sink where all events are piped
     *
     */
    public JKCloudEventSink(String name, String url, String token, EventFormatter frm, EventSink sink) {
        super(name, frm);
        this.url = url;
        this.logSink = sink;
        this.accessToken = token;
    }

    /**
     * Gets the access token used to establish authenticated connections to Analyzer.
     *
     * @return access token
     */
    public String getAccessToken() {
        return accessToken;
    }

    /**
     * Sets the access token to use when establishing authenticated connections to Analyzer.
     *
     * @param accessToken
     *            the access token
     */
    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void resetStats() {
        sentBytes.set(0);
        lastBytes.set(0);
        sentMsgs.set(0);
        super.resetStats();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public KeyValueStats getStats(Map<String, Object> stats) {
        super.getStats(stats);
        stats.put(Utils.qualify(this, KEY_SENT_BYTES), sentBytes);
        stats.put(Utils.qualify(this, KEY_LAST_BYTES), lastBytes);
        stats.put(Utils.qualify(this, KEY_SENT_MSGS), sentMsgs);
        stats.put(Utils.qualify(this, KEY_SERVICE_URL), url);
        return this;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Object getSinkHandle() {
        return jkHandle;
    }

    /**
     * Indicates whether connection to remote destination is open and available.
     *
     * @return {@code true} if connection open, {@code false} otherwise.
     */
    @Override
    public synchronized boolean isOpen() {
        return (jkHandle != null && jkHandle.isConnected());
    }

    @Override
    public synchronized void open() throws IOException {
        try {
            close();
            logger.log(OpLevel.DEBUG, "Open name={3}, url={0}, proxy.host={1}, proxy.port={2}", url, proxyHost,
                    proxyPort, this.getName());
            jkHandle = new JKClient(url, proxyHost, proxyPort, logger);
            if (!StringUtils.isEmpty(accessToken)) {
                jkHandle.connect(accessToken);
            } else {
                jkHandle.connect();
            }
            if (logSink != null && !logSink.isOpen()) {
                logSink.open();
            }
        } catch (URISyntaxException e) {
            logger.log(OpLevel.ERROR, "Failed to open name={3}, url={0}, proxy.host={1}, proxy.port={2}", url,
                    proxyHost, proxyPort, this.getName(), e);
            close();
            throw new IOException(e.getMessage(), e);
        }
    }

    @Override
    public synchronized void close() throws IOException {
        if (isOpen()) {
            logger.log(OpLevel.DEBUG, "Closing name={3}, url={0}, proxy.host={1}, proxy.port={2}", url, proxyHost,
                    proxyPort, this.getName());
            jkHandle.close();
        }
        if (logSink != null && logSink.isOpen()) {
            logSink.close();
        }
    }

    @Override
    public String toString() {
        return super.toString() + "(url: " + url + ", jk.handle: " + jkHandle + ", piped.sink: " + logSink + ")";
    }

    private void writeLine(String msg) throws IOException {
        if (StringUtils.isEmpty(msg))
            return;
        _checkState();
        String lineMsg = msg.endsWith("\n") ? msg : msg + "\n";
        jkHandle.send(lineMsg, false);
        sentMsgs.incrementAndGet();
        lastBytes.set(lineMsg.length());
        sentBytes.addAndGet(lineMsg.length());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void _write(Object msg, Object... args) throws IOException {
        writeLine(getEventFormatter().format(msg, args));
    }

    @Override
    protected void _log(TrackingEvent event) throws IOException {
        if (logSink != null && logSink.isSet(event.getSeverity())) {
            logSink.log(event);
        }
        writeLine(getEventFormatter().format(event));
    }

    @Override
    protected void _log(TrackingActivity activity) throws IOException {
        if (logSink != null && logSink.isSet(activity.getSeverity())) {
            logSink.log(activity);
        }
        writeLine(getEventFormatter().format(activity));
    }

    @Override
    protected void _log(long ttl, Source src, OpLevel sev, String msg, Object... args) throws IOException {
        if (logSink != null && logSink.isSet(sev)) {
            logSink.log(ttl, src, sev, msg, args);
        }
        writeLine(getEventFormatter().format(ttl, src, sev, msg, args));
    }

    @Override
    protected void _log(Snapshot snapshot) throws Exception {
        if (logSink != null && logSink.isSet(snapshot.getSeverity())) {
            logSink.log(snapshot);
        }
        writeLine(getEventFormatter().format(snapshot));
    }

    @Override
    public boolean isSet(OpLevel sev) {
        return true;
    }

    @Override
    protected void _checkState() throws IllegalStateException {
        if (!isOpen())
            throw new IllegalStateException(
                    "Sink closed name=" + getName() + ", url=" + url + ", handle=" + jkHandle);
    }
}