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

com.stackify.error.logback.StackifyErrorAppender Maven / Gradle / Ivy

/*
 * Copyright 2013 Stackify
 *
 * 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.stackify.error.logback;

import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.ThrowableProxy;
import ch.qos.logback.core.AppenderBase;

import com.stackify.api.ApiClient;
import com.stackify.api.EnvironmentDetail;
import com.stackify.api.StackifyError;
import com.stackify.api.common.ApiClients;
import com.stackify.api.common.EnvironmentDetails;
import com.stackify.api.common.http.StackifyErrorSender;
import com.stackify.api.common.lang.Throwables;
import com.stackify.api.json.StackifyErrorConverter;

/**
 * Logback logger appender for sending exceptions to Stackify.
 * 
 * 

* Example: *

 * {@code
 * 
 *	 YOUR_API_KEY
 *	 YOUR_APPLICATION_NAME
 *	 YOUR_ENVIRONMENT
 * 
 * }
 * 
* * @author Eric Martin */ public class StackifyErrorAppender extends AppenderBase { /** * The class responsible for sending the errors to Stackify */ private StackifyErrorSender errorSender; /** * The API Client */ private ApiClient apiClient = null; /** * The environment detail */ private EnvironmentDetail environmentDetail = null; /** * API URL (Appender configuration parameter) */ private String apiUrl = "https://api.stackify.com/Error/V1"; /** * API Key (Appender configuration parameter) */ private String apiKey = null; /** * Application name (Appender configuration parameter) */ private String application = null; /** * Environment (Appender configuration parameter) */ private String environment = null; /** * JSON Converter (Appender configuration parameter) */ private String converter = "com.stackify.api.json.jackson.StackifyErrorJacksonConverter"; /** * @return the apiUrl */ public String getApiUrl() { return apiUrl; } /** * @param apiUrl the apiUrl to set */ public void setApiUrl(String apiUrl) { this.apiUrl = apiUrl; } /** * @return the apiKey */ public String getApiKey() { return apiKey; } /** * @param apiKey the apiKey to set */ public void setApiKey(String apiKey) { this.apiKey = apiKey; } /** * @return the application */ public String getApplication() { return application; } /** * @param application the application to set */ public void setApplication(String application) { this.application = application; } /** * @return the environment */ public String getEnvironment() { return environment; } /** * @param environment the environment to set */ public void setEnvironment(String environment) { this.environment = environment; } /** * @return the converter */ public String getConverter() { return converter; } /** * @param converter the converter to set */ public void setConverter(String converter) { this.converter = converter; } /** * @return the errorSender */ protected StackifyErrorSender getErrorSender() { return errorSender; } /** * @return the apiClient */ protected ApiClient getApiClient() { return apiClient; } /** * @return the environmentDetail */ protected EnvironmentDetail getEnvironmentDetail() { return environmentDetail; } /** * @see ch.qos.logback.core.AppenderBase#start() */ @Override public void start() { super.start(); // check the api key if ((apiKey == null) || (apiKey.isEmpty())) { addError("API Key not set for the Stackify Error Appender"); return; } // build the static API client record this.apiClient = ApiClients.getApiClient(StackifyErrorAppender.class, "/stackify-error-logback.properties"); // build the static environment details record this.environmentDetail = EnvironmentDetails.getEnvironmentDetail(application, environment); // load the JSON converter try { Class converterClass = Class.forName(converter); StackifyErrorConverter converterInstance = (StackifyErrorConverter) converterClass.newInstance(); errorSender = new StackifyErrorSender(converterInstance); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } /** * @see ch.qos.logback.core.AppenderBase#append(java.lang.Object) */ @Override protected void append(final ILoggingEvent event) { // Make sure the API Key is set if ((apiKey == null) || (apiKey.isEmpty())) { return; } // Get the exception from the event // If it was ERROR without an exception, create a placeholder for the stack trace Throwable exception = getThrowable(event); if (exception == null) { if (event.getLevel() == Level.ERROR) { exception = new Throwable(); } else { return; } } try { // Build the tags for the error event List tags = new ArrayList(); tags.add("logback"); tags.add(event.getLevel().toString().toLowerCase()); tags.add(event.getLoggerName()); // Build the StackifyError POJO from the LoggingEvent StackifyError.Builder errorBuilder = StackifyError.newBuilder(); errorBuilder.apiClient(apiClient); errorBuilder.environmentDetail(environmentDetail); errorBuilder.occurredEpochMillis(new Date(event.getTimeStamp())); errorBuilder.error(Throwables.toErrorItem(exception)); errorBuilder.tags(tags); StackifyError error = errorBuilder.build(); // Send the error to Stackify int rc = errorSender.send(apiUrl, apiKey, Collections.singletonList(error)); if (rc != HttpURLConnection.HTTP_OK) { addInfo("Stackify Error Service returned HTTP " + Integer.toString(rc)); } } catch (Throwable t) { addInfo("Exception posting to Stackify Error Service", t); } } /** * Returns the exception tied to this log event * @param event The log event * @return The Throwable or null */ private Throwable getThrowable(final ILoggingEvent event) { IThrowableProxy iThrowableProxy = event.getThrowableProxy(); if (iThrowableProxy != null) { if (iThrowableProxy instanceof ThrowableProxy) { ThrowableProxy throwableProxy = (ThrowableProxy) iThrowableProxy; return throwableProxy.getThrowable(); } } return null; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy