Skip to content

Commit

Permalink
Allow the use LOGBack appenders
Browse files Browse the repository at this point in the history
Add an optional dependency to the forthcoming plugin that includes
the LOGBack appender to push events to the NATS pub/sub broker.

LOGBack (https://logback.qos.ch/) is a very powerful and versatile
logging system that allows to decouple the generation of events from
the underlying transport method.

A new option "Enable publish of events to LOGBack" will send all the
events to LOGBack as well, so that other ways of communications
can be implemented to offload all the events outside the Jenkins box.

Change-Id: I595b3a1f3460443cf26c1a68d8581a247f520505
  • Loading branch information
lucamilanesio committed Apr 30, 2018
1 parent a412491 commit 7548ea8
Show file tree
Hide file tree
Showing 15 changed files with 256 additions and 28 deletions.
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@
<artifactId>jackson-databind</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>logback-nats-appender</artifactId>
<version>0.2.2</version>
<optional>true</optional>
</dependency>

<!-- Test dependancies -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class StatisticsConfiguration extends GlobalConfiguration {
private String awsAccessKey;
private String awsSecretKey;
private String snsTopicArn;
private String logbackConfigXmlUrl;

private Boolean queueInfo;
private Boolean buildInfo;
Expand All @@ -36,6 +37,8 @@ public class StatisticsConfiguration extends GlobalConfiguration {
private Boolean shouldSendApiHttpRequests;
private Boolean shouldPublishToAwsSnsQueue;

private Boolean shouldSendToLogback;

public StatisticsConfiguration() {
load();
}
Expand Down Expand Up @@ -359,4 +362,20 @@ public FormValidation doCheckAwsSecretKey(
private boolean validateProtocolUsed(String url) {
return !(url.startsWith("http://") || url.startsWith("https://"));
}

public Boolean getShouldSendToLogback() {
return shouldSendToLogback;
}

public void setShouldSendToLogback(Boolean shouldSendToLogback) {
this.shouldSendToLogback = shouldSendToLogback;
}

public String getLogbackConfigXmlUrl() {
return logbackConfigXmlUrl;
}

public void setLogbackConfigXmlUrl(String logbackConfigXmlUrl) {
this.logbackConfigXmlUrl = logbackConfigXmlUrl;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import hudson.model.BuildStepListener;
import hudson.tasks.BuildStep;
import org.jenkins.plugins.statistics.gatherer.model.step.BuildStepStats;
import org.jenkins.plugins.statistics.gatherer.util.LogbackUtil;
import org.jenkins.plugins.statistics.gatherer.util.PropertyLoader;
import org.jenkins.plugins.statistics.gatherer.util.RestClientUtil;
import org.jenkins.plugins.statistics.gatherer.util.SnsClientUtil;
Expand All @@ -29,6 +30,7 @@ public void finished(AbstractBuild build, BuildStep bs, BuildListener listener,
buildStepStats.setStartTime(new Date(0));
RestClientUtil.postToService(getRestUrl(), buildStepStats);
SnsClientUtil.publishToSns(buildStepStats);
LogbackUtil.info(buildStepStats);
}
}

Expand All @@ -43,6 +45,7 @@ public void started(AbstractBuild build, BuildStep bs, BuildListener listener) {
buildStepStats.setEndTime(new Date(0));
RestClientUtil.postToService(getRestUrl(), buildStepStats);
SnsClientUtil.publishToSns(buildStepStats);
LogbackUtil.info(buildStepStats);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@
import hudson.model.listeners.ItemListener;
import jenkins.model.Jenkins;
import org.jenkins.plugins.statistics.gatherer.model.job.JobStats;
import org.jenkins.plugins.statistics.gatherer.util.Constants;
import org.jenkins.plugins.statistics.gatherer.util.PropertyLoader;
import org.jenkins.plugins.statistics.gatherer.util.RestClientUtil;
import org.jenkins.plugins.statistics.gatherer.util.SnsClientUtil;
import org.jenkins.plugins.statistics.gatherer.util.*;

import java.io.IOException;
import java.util.Date;
Expand Down Expand Up @@ -39,6 +36,7 @@ public void onCreated(Item item) {
setConfig(project, ciJob);
RestClientUtil.postToService(getRestUrl(), ciJob);
SnsClientUtil.publishToSns(ciJob);
LogbackUtil.info(ciJob);
} catch (Exception e) {
logException(item, e);
}
Expand Down Expand Up @@ -84,8 +82,10 @@ private JobStats addCIJobData(AbstractProject<?, ?> project) {
ciJob.setJobUrl(project.getUrl());
String userName = Jenkins.getAuthentication().getName();
User user = Jenkins.getInstance().getUser(userName);
ciJob.setUserId(user.getId());
ciJob.setUserName(user.getFullName());
if(user != null) {
ciJob.setUserId(user.getId());
ciJob.setUserName(user.getFullName());
}

return ciJob;
}
Expand Down Expand Up @@ -116,6 +116,7 @@ public void onUpdated(Item item) {
setConfig(project, ciJob);
RestClientUtil.postToService(getRestUrl(), ciJob);
SnsClientUtil.publishToSns(ciJob);
LogbackUtil.info(ciJob);
} catch (Exception e) {
logException(item, e);
}
Expand All @@ -132,6 +133,7 @@ public void onDeleted(Item item) {
ciJob.setStatus(Constants.DELETED);
RestClientUtil.postToService(getRestUrl(), ciJob);
SnsClientUtil.publishToSns(ciJob);
LogbackUtil.info(ciJob);
} catch (Exception e) {
logException(item, e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public void onEnterWaiting(WaitingItem waitingItem) {
addEntryQueueCause("waiting", waitingItem, queue);
}
RestClientUtil.postToService(getRestUrl(), queue);
LogbackUtil.info(queue);
} catch (Exception e) {
logExceptionWaiting(waitingItem, e);
}
Expand Down Expand Up @@ -73,6 +74,7 @@ public void onLeaveWaiting(WaitingItem waitingItem) {
}
RestClientUtil.postToService(getRestUrl(), queue);
SnsClientUtil.publishToSns(queue);
LogbackUtil.info(queue);
} catch (Exception e) {
logExceptionWaiting(waitingItem, e);
}
Expand Down Expand Up @@ -127,6 +129,7 @@ public void onLeaveBlocked(BlockedItem blockedItem) {

RestClientUtil.postToService(getRestUrl(), queue);
SnsClientUtil.publishToSns(queue);
LogbackUtil.info(queue);
} catch (Exception e) {
logExceptionBlocked(blockedItem, e);
}
Expand All @@ -143,6 +146,7 @@ public void onEnterBuildable(BuildableItem buildableItem) {
}
RestClientUtil.postToService(getRestUrl(), queue);
SnsClientUtil.publishToSns(queue);
LogbackUtil.info(queue);
} catch (Exception e) {
logExceptionLeave(buildableItem, e);
}
Expand All @@ -159,6 +163,7 @@ public void onLeaveBuildable(BuildableItem buildableItem) {
}
RestClientUtil.postToService(getRestUrl(), queue);
SnsClientUtil.publishToSns(queue);
LogbackUtil.info(queue);
} catch (Exception e) {
logExceptionLeave(buildableItem, e);
}
Expand Down Expand Up @@ -215,6 +220,7 @@ public void onLeft(LeftItem leftItem) {
queue.setContextId(leftItem.outcome.hashCode());
RestClientUtil.postToService(getRestUrl(), queue);
SnsClientUtil.publishToSns(queue);
LogbackUtil.info(queue);
} catch (Exception e) {
logExceptionLeft(leftItem, e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public void onStarted(Run<?, ?> run, TaskListener listener) {
addSlaveInfo(run, build, listener);
RestClientUtil.postToService(getRestUrl(), build);
SnsClientUtil.publishToSns(build);
LogbackUtil.info(build);
LOGGER.log(Level.INFO, "Started build and its status is : " + buildResult +
" and start time is : " + run.getTimestamp().getTime());
} catch (Exception e) {
Expand Down Expand Up @@ -226,6 +227,7 @@ public void onFinalized(final Run<?, ?> run) {
addBuildFailureCauses(build);
RestClientUtil.postToService(getRestUrl(), build);
SnsClientUtil.publishToSns(build);
LogbackUtil.info(build);
LOGGER.log(Level.INFO, run.getParent().getName() + " build is completed " +
"its status is : " + buildResult +
" at time : " + new Date());
Expand Down Expand Up @@ -272,6 +274,7 @@ public Environment setUpEnvironment(AbstractBuild build,
scmCheckoutInfo.setEndTime(new Date(0));
RestClientUtil.postToService(getScmCheckoutUrl(), scmCheckoutInfo);
SnsClientUtil.publishToSns(scmCheckoutInfo);
LogbackUtil.info(scmCheckoutInfo);
}
return super.setUpEnvironment(build, launcher, listener);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import hudson.scm.SCM;
import hudson.scm.SCMRevisionState;
import org.jenkins.plugins.statistics.gatherer.model.scm.ScmCheckoutInfo;
import org.jenkins.plugins.statistics.gatherer.util.LogbackUtil;
import org.jenkins.plugins.statistics.gatherer.util.PropertyLoader;
import org.jenkins.plugins.statistics.gatherer.util.RestClientUtil;
import org.jenkins.plugins.statistics.gatherer.util.SnsClientUtil;
Expand All @@ -35,6 +36,7 @@ public void onCheckout(Run<?,?> run, SCM scm, FilePath workspace, TaskListener l
scmCheckoutInfo.setEndTime(Calendar.getInstance().getTime());
RestClientUtil.postToService(getUrl(), scmCheckoutInfo);
SnsClientUtil.publishToSns(scmCheckoutInfo);
LogbackUtil.info(scmCheckoutInfo);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.jenkins.plugins.statistics.gatherer.util;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.util.ContextInitializer;
import ch.qos.logback.core.joran.spi.JoranException;

import java.net.MalformedURLException;
import java.net.URL;

public class LogbackUtil {
private static final String STATISTICS_GATHERER_LOGGER = "statistics-gatherer";
private static Logger logger;

private static Logger getLogger(String loggerName) {
LoggerContext loggerContext = new LoggerContext();
ContextInitializer contextInitializer = new ContextInitializer(loggerContext);
try {
String configurationUrlString = PropertyLoader.getLogbackConfigXmlUrl();
if (configurationUrlString == null) {
throw new IllegalStateException("LOGBack XML configuration file not specified");
}

URL configurationUrl = new URL(configurationUrlString);
contextInitializer.configureByResource(configurationUrl);
return loggerContext.getLogger(loggerName);
} catch (JoranException e) {
throw new RuntimeException("Unable to configure logger", e);
} catch (MalformedURLException e) {
throw new RuntimeException("Unable to find LOGBack XML configuration", e);
}
}

public static void info(Object object) {
if (PropertyLoader.getShouldSendToLogback()) {
if(logger == null) {
synchronized (LogbackUtil.class) {
logger = getLogger(STATISTICS_GATHERER_LOGGER);
}
}
logger.info(JSONUtil.convertToJson(object));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.jenkins.plugins.statistics.gatherer.util;

import com.google.common.base.Strings;
import hudson.EnvVars;
import hudson.slaves.EnvironmentVariablesNodeProperty;
import hudson.slaves.NodeProperty;
Expand Down Expand Up @@ -54,18 +55,31 @@ public String getProperty(
for (EnvironmentVariablesNodeProperty environmentVariablesNodeProperty : properties) {
environmentVariables.putAll(environmentVariablesNodeProperty.getEnvVars());
}
final String value = environmentVariables.get(key);
if (value == null || value.isEmpty()) {
return getResourceBundleProperty(key);
String value = environmentVariables.get(key);
if (!Strings.isNullOrEmpty(value)) {
return value;
}
return value;
value = environmentVariables.get(key.toLowerCase());
if (!Strings.isNullOrEmpty(value)) {
return value;
}

value = getResourceBundleProperty(key);
if (!Strings.isNullOrEmpty(value)) {
return value;
}
return getResourceBundleProperty(key.toLowerCase());
}

public static String getEnvironmentProperty(
final String key) {
return getInstance().getProperty(key);
}

public static boolean isTrue(String value) {
return value != null ? value.toLowerCase().equals("true") : false;
}

public static String getQueueEndPoint() {
String endPoint = StatisticsConfiguration.get().getQueueUrl();
if (endPoint != null && !endPoint.isEmpty()) {
Expand Down Expand Up @@ -153,60 +167,70 @@ public static Boolean getQueueInfo() {
return queueInfo;
}
String queueInfoEnv = getEnvironmentProperty("statistics.endpoint.queueInfo");
return "true".equals(queueInfoEnv);
return isTrue(queueInfoEnv);
}

public static Boolean getBuildInfo() {
Boolean buildInfo = StatisticsConfiguration.get().getBuildInfo();
if (buildInfo != null) {
return buildInfo;
}
String buildInfoEnv = getEnvironmentProperty("statistics.endpoint.buildInfo");
return "true".equals(buildInfoEnv);
return isTrue(getEnvironmentProperty("statistics.endpoint.buildInfo"));
}

public static Boolean getProjectInfo() {
Boolean projectInfo = StatisticsConfiguration.get().getProjectInfo();
if (projectInfo != null) {
return projectInfo;
}
String projectInfoEnv = getEnvironmentProperty("statistics.endpoint.projectInfo");
return "true".equals(projectInfoEnv);
return isTrue(getEnvironmentProperty("statistics.endpoint.projectInfo"));
}

public static Boolean getBuildStepInfo() {
Boolean buildStepInfo = StatisticsConfiguration.get().getBuildStepInfo();
if (buildStepInfo != null) {
return buildStepInfo;
}
String buildStepInfoEnv = getEnvironmentProperty("statistics.endpoint.buildStepInfo");
return "true".equals(buildStepInfoEnv);
return isTrue(getEnvironmentProperty("statistics.endpoint.buildStepInfo"));
}

public static Boolean getScmCheckoutInfo() {
Boolean scmCheckoutInfo = StatisticsConfiguration.get().getScmCheckoutInfo();
if (scmCheckoutInfo != null) {
return scmCheckoutInfo;
}
String scmCheckoutInfoEnv = getEnvironmentProperty("statistics.endpoint.scmCheckoutInfo");
return "true".equals(scmCheckoutInfoEnv);
return isTrue(getEnvironmentProperty("statistics.endpoint.scmCheckoutInfo"));
}

public static Boolean getShouldSendApiHttpRequests() {
Boolean shouldSendApiHttpRequests = StatisticsConfiguration.get().getShouldSendApiHttpRequests();
if (shouldSendApiHttpRequests != null) {
return shouldSendApiHttpRequests;
}
String shouldSendApiHttpRequestsInfoEnv = getEnvironmentProperty("statistics.endpoint.shouldSendApiHttpRequests");
return "true".equals(shouldSendApiHttpRequestsInfoEnv);
return isTrue(getEnvironmentProperty("statistics.endpoint.shouldSendApiHttpRequests"));
}

public static Boolean getShouldPublishToAwsSnsQueue() {
Boolean shouldPublishToAwsSnsQueue = StatisticsConfiguration.get().getShouldPublishToAwsSnsQueue();
if (shouldPublishToAwsSnsQueue != null) {
return shouldPublishToAwsSnsQueue;
}
String shouldPublishToAwsSnsQueueEnv = getEnvironmentProperty("statistics.endpoint.shouldPublishToAwsSnsQueue");
return "true".equals(shouldPublishToAwsSnsQueueEnv);
return isTrue(getEnvironmentProperty("statistics.endpoint.shouldPublishToAwsSnsQueue"));
}

public static boolean getShouldSendToLogback() {
Boolean shouldSendToLogback = StatisticsConfiguration.get().getShouldSendToLogback();
if (shouldSendToLogback != null) {
return shouldSendToLogback;
}
return isTrue(getEnvironmentProperty("statistics.endpoint.shouldSendToLogback"));
}

public static String getLogbackConfigXmlUrl() {
String logbackConfigXmlUrlString = StatisticsConfiguration.get().getLogbackConfigXmlUrl();
if (logbackConfigXmlUrlString == null) {
logbackConfigXmlUrlString = getEnvironmentProperty("statistics.endpoint.logbackConfigXmlUrl");
}
return logbackConfigXmlUrlString;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,13 @@ f.section(title:_("Statistics Gatherer")) {
f.entry(title:_("Enable HTTP publishing?"), field:"shouldSendApiHttpRequests") {
f.checkbox(default: instance.shouldSendApiHttpRequests == null ? false : instance.shouldSendApiHttpRequests.equals(true));
}

f.entry(title:_("Enable publish of events to LOGBack"), field:"shouldSendToLogback") {
f.checkbox()
}

f.entry(title:_("LOGBack XML configuration URL"), field:"logbackConfigXmlUrl") {
f.textbox()
}
}
}
Loading

0 comments on commit 7548ea8

Please sign in to comment.