From 7a2c23b3ad83eab0eed5b990c70a1603447d5ee5 Mon Sep 17 00:00:00 2001 From: "Singla, Rajiv (rs153v)" Date: Wed, 15 Aug 2018 11:46:10 -0400 Subject: Standalone TCA with EELF Logger Issue-ID: DCAEGEN2-633 Change-Id: I4da76b532021c0d6248455e7bd6e77f4614c35a7 Signed-off-by: Singla, Rajiv (rs153v) --- .../eelf/logger/logback/EELFLoggerDefaults.java | 105 ++++ .../eelf/logger/logback/filter/MarkerFilter.java | 71 +++ .../eelf/logger/logback/layout/AuditLogLayout.java | 81 +++ .../eelf/logger/logback/layout/ConsoleLayout.java | 56 ++ .../eelf/logger/logback/layout/DebugLogLayout.java | 54 ++ .../eelf/logger/logback/layout/ErrorLogLayout.java | 64 +++ .../logger/logback/layout/MetricLogLayout.java | 83 +++ .../logback/listener/LogbackStartupListener.java | 128 +++++ .../eelf/logger/logback/log/AuditLogImpl.java | 119 +++++ .../eelf/logger/logback/log/DebugLogImpl.java | 88 +++ .../logger/logback/log/EELFLoggerContextImpl.java | 57 ++ .../eelf/logger/logback/log/EELFLoggerImpl.java | 81 +++ .../eelf/logger/logback/log/ErrorLogImpl.java | 98 ++++ .../eelf/logger/logback/log/MetricLogImpl.java | 120 +++++ .../resolver/CompositePropertyResolver.java | 53 ++ .../resolver/EnvironmentPropertyResolver.java | 46 ++ .../logger/logback/resolver/PropertyResolver.java | 41 ++ .../logback/resolver/SystemPropertyResolver.java | 59 +++ .../utils/eelf/logger/logback/utils/LogUtils.java | 590 +++++++++++++++++++++ ....onap.dcae.utils.eelf.logger.api.log.EELFLogger | 20 + .../src/main/resources/eelf-async-appenders.xml | 55 ++ .../src/main/resources/eelf-defaults.xml | 51 ++ .../src/main/resources/eelf-logback.xml | 45 ++ .../src/main/resources/eelf-optional-appenders.xml | 68 +++ .../src/main/resources/eelf-required-appenders.xml | 112 ++++ 25 files changed, 2345 insertions(+) create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/EELFLoggerDefaults.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/filter/MarkerFilter.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/AuditLogLayout.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/ConsoleLayout.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/DebugLogLayout.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/ErrorLogLayout.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/MetricLogLayout.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/listener/LogbackStartupListener.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/AuditLogImpl.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/DebugLogImpl.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/EELFLoggerContextImpl.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/EELFLoggerImpl.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/ErrorLogImpl.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/MetricLogImpl.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/CompositePropertyResolver.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/EnvironmentPropertyResolver.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/PropertyResolver.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/SystemPropertyResolver.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/utils/LogUtils.java create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/resources/META-INF/services/org.onap.dcae.utils.eelf.logger.api.log.EELFLogger create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-async-appenders.xml create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-defaults.xml create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-logback.xml create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-optional-appenders.xml create mode 100644 eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-required-appenders.xml (limited to 'eelf-logger/eelf-logger-logback-impl/src/main') diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/EELFLoggerDefaults.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/EELFLoggerDefaults.java new file mode 100644 index 0000000..eceaf20 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/EELFLoggerDefaults.java @@ -0,0 +1,105 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback; + + +import org.onap.dcae.utils.eelf.logger.api.info.LogInfo; +import org.onap.dcae.utils.eelf.logger.model.info.AppLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.CustomFieldsLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.ErrorLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.MiscLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.RequestTimingLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.ResponseLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.ServiceLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.TargetServiceLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.OptionalLogSpecImpl; + +import java.util.Date; + +import static org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils.createDefaultAppLogInfo; + + +/** + * This utility class various default implementations for EELF Logger. Users should use these default rather then + * creating their own {@link LogInfo} objects. + * + * @author Rajiv Singla + */ +public class EELFLoggerDefaults { + + private static final String UNKNOWN_FIELD_VALUE = "UNKNOWN"; + + // =============== APP LOG SPEC ======================// + /** + * Provides Default {@link AppLogInfoImpl} + */ + public static final AppLogInfoImpl DEFAULT_APP_LOG_INFO = createDefaultAppLogInfo(); + + + // =============== AUDIT LOG SPEC ===================== // + + private static final String DEFAULT_PARTNER_NAME = + System.getProperty("user.name") != null ? System.getProperty("user.name") : UNKNOWN_FIELD_VALUE; + + public static final ServiceLogInfoImpl DEFAULT_SERVICE_LOG_INFO = + new ServiceLogInfoImpl(UNKNOWN_FIELD_VALUE, DEFAULT_PARTNER_NAME, ""); + + + public static final RequestTimingLogInfoImpl DEFAULT_REQUEST_TIMING_LOG_INFO = + new RequestTimingLogInfoImpl(new Date(), new Date(), null); + + + public static final ResponseLogInfoImpl DEFAULT_RESPONSE_LOG_INFO = + new ResponseLogInfoImpl(900, "UNDEFINED"); + + + // =============== METRIC LOG SPEC ===================== // + + public static final TargetServiceLogInfoImpl DEFAULT_TARGET_SERVICE_LOG_INFO = + new TargetServiceLogInfoImpl(UNKNOWN_FIELD_VALUE, UNKNOWN_FIELD_VALUE, UNKNOWN_FIELD_VALUE); + + // =============== ERROR LOG SPEC ===================== // + + public static final ErrorLogInfoImpl DEFAULT_ERROR_LOG_INFO = + new ErrorLogInfoImpl(900, "UNDEFINED ERROR"); + + + // ============= OPTIONAL LOG SPEC =================== // + + /** + * Provides Default {@link CustomFieldsLogInfoImpl} + */ + public static final CustomFieldsLogInfoImpl DEFAULT_CUSTOM_FIELDS_LOG_INFO = + new CustomFieldsLogInfoImpl("", "", "", ""); + + /** + * Provides Default {@link MiscLogInfoImpl} + */ + public static final MiscLogInfoImpl DEFAULT_MISC_LOG_INFO = new MiscLogInfoImpl("", ""); + + + /** + * Provides Default {@link OptionalLogSpecImpl} + */ + public static final OptionalLogSpecImpl DEFAULT_OPTIONAL_LOG_SPEC = new OptionalLogSpecImpl(null, null, + DEFAULT_CUSTOM_FIELDS_LOG_INFO, DEFAULT_MISC_LOG_INFO); + + +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/filter/MarkerFilter.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/filter/MarkerFilter.java new file mode 100644 index 0000000..a664190 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/filter/MarkerFilter.java @@ -0,0 +1,71 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.filter; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.filter.AbstractMatcherFilter; +import ch.qos.logback.core.spi.FilterReply; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; + +import java.util.HashSet; +import java.util.Set; + +/** + * Logback Marker filter + * + * @author Rajiv Singla + */ +public class MarkerFilter extends AbstractMatcherFilter { + + private String markersString; + private Set markersToAccept = new HashSet<>(); + + @Override + public FilterReply decide(final ILoggingEvent event) { + + if (!isStarted()) { + return FilterReply.NEUTRAL; + } + + if (markersToAccept.contains(event.getMarker())) { + return onMatch; + } else { + return onMismatch; + } + } + + public void setMarkers(String markersString) { + this.markersString = markersString; + } + + + public void start() { + + if (markersString != null && markersString.trim().split(",").length > 0) { + + final String[] markerStrings = markersString.trim().split(","); + for (String markerString : markerStrings) { + markersToAccept.add(MarkerFactory.getMarker(markerString.trim())); + } + super.start(); + } + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/AuditLogLayout.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/AuditLogLayout.java new file mode 100644 index 0000000..5d848ac --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/AuditLogLayout.java @@ -0,0 +1,81 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.layout; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.LayoutBase; +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.spec.AppLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.AuditLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; + + +/** + * Audit log layout generates log messages as per EELF Audit Log Specifications + * + * @author Rajiv Singla + */ +public class AuditLogLayout extends LayoutBase { + + @Override + public String doLayout(final ILoggingEvent event) { + + final AppLogSpec appLogSpec = LogUtils.getAppLogSpec(); + final LogLevelCategory logLevelCategory = LogUtils.getLogLevelCategory(); + final Class loggerClass = LogUtils.getLoggerClass(); + final OptionalLogSpec optionalLogSpec = LogUtils.getOptionalLogSpec(loggerClass, logLevelCategory); + final AuditLogSpec auditLogSpec = LogUtils.getAuditLogSpec(); + + final String beginTimestamp = LogUtils.formatDate(auditLogSpec.getBeginTimestamp()); + final String endTimestamp = LogUtils.formatDate(auditLogSpec.getEndTimestamp()); + + final String[] auditLogValues = { + beginTimestamp, + endTimestamp, + auditLogSpec.getRequestId(), + appLogSpec.getServiceInstanceID(), + event.getThreadName(), + appLogSpec.getVirtualServerName(), + auditLogSpec.getServiceName(), + auditLogSpec.getPartnerName(), + optionalLogSpec.getStatusCode().name(), + auditLogSpec.getResponseCode().toString(), + auditLogSpec.getResponseDescription(), + appLogSpec.getInstanceUUID(), + logLevelCategory != null ? logLevelCategory.name() : "", + optionalLogSpec.getAlertSeverity().getSeverityCode(), + appLogSpec.getServerIPAddress(), + auditLogSpec.getElapsedTime().toString(), + appLogSpec.getServerFQDN(), + auditLogSpec.getClientIPAddress(), + optionalLogSpec.getClassName(), + optionalLogSpec.getUnused(), + optionalLogSpec.getProcessId(), + optionalLogSpec.getCustomField1(), + optionalLogSpec.getCustomField2(), + optionalLogSpec.getCustomField3(), + optionalLogSpec.getCustomField4(), + event.getFormattedMessage() + }; + + return LogUtils.createLogMessageString(auditLogValues); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/ConsoleLayout.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/ConsoleLayout.java new file mode 100644 index 0000000..589d863 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/ConsoleLayout.java @@ -0,0 +1,56 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.layout; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.LayoutBase; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; +import org.slf4j.Marker; + +/** + * Console layout is used to log messages on the console for debugging purposes. + * + * @author Rajiv Singla + */ +public class ConsoleLayout extends LayoutBase { + + private static final MetricLogLayout METRIC_LOG_LAYOUT = new MetricLogLayout(); + private static final AuditLogLayout AUDIT_LOG_LAYOUT = new AuditLogLayout(); + private static final ErrorLogLayout ERROR_LOG_LAYOUT = new ErrorLogLayout(); + private static final DebugLogLayout DEBUG_LOG_LAYOUT = new DebugLogLayout(); + + @Override + public String doLayout(final ILoggingEvent event) { + + final Marker eventMarker = event.getMarker(); + + if (eventMarker.equals(LogUtils.AUDIT_LOG_MARKER)) { + return AUDIT_LOG_LAYOUT.doLayout(event); + } else if (eventMarker.equals(LogUtils.METRIC_LOG_MARKER)) { + return METRIC_LOG_LAYOUT.doLayout(event); + } else if (eventMarker.equals(LogUtils.ERROR_LOG_MARKER)) { + return ERROR_LOG_LAYOUT.doLayout(event); + } else if (eventMarker.equals(LogUtils.DEBUG_LOG_MARKER)) { + return DEBUG_LOG_LAYOUT.doLayout(event); + } + + return "Console Layout not defined for Marker: " + eventMarker; + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/DebugLogLayout.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/DebugLogLayout.java new file mode 100644 index 0000000..e7b1cd4 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/DebugLogLayout.java @@ -0,0 +1,54 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.layout; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.LayoutBase; +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.spec.DebugLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; + + +/** + * @author Rajiv Singla + */ +public class DebugLogLayout extends LayoutBase { + + @Override + public String doLayout(final ILoggingEvent event) { + + final LogLevelCategory logLevelCategory = LogUtils.getLogLevelCategory(); + final Class loggerClass = LogUtils.getLoggerClass(); + final OptionalLogSpec optionalLogSpec = LogUtils.getOptionalLogSpec(loggerClass, logLevelCategory); + + final DebugLogSpec debugLogSpec = LogUtils.getDebugLogSpec(); + + final String creationTimestamp = LogUtils.formatDate(optionalLogSpec.getCreationTimestamp()); + + final String[] debugLogValues = { + creationTimestamp, + debugLogSpec.getRequestId(), + event.getFormattedMessage() + }; + + return LogUtils.createLogMessageString(debugLogValues); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/ErrorLogLayout.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/ErrorLogLayout.java new file mode 100644 index 0000000..4eefe36 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/ErrorLogLayout.java @@ -0,0 +1,64 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.layout; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.LayoutBase; +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.spec.ErrorLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; + + +/** + * Error Log Layout generates log messages as per EELF Error Log Specifications + * + * @author Rajiv Singla + */ +public class ErrorLogLayout extends LayoutBase { + + @Override + public String doLayout(final ILoggingEvent event) { + + final LogLevelCategory logLevelCategory = LogUtils.getLogLevelCategory(); + final Class loggerClass = LogUtils.getLoggerClass(); + final OptionalLogSpec optionalLogSpec = LogUtils.getOptionalLogSpec(loggerClass, logLevelCategory); + + final ErrorLogSpec errorLogSpec = LogUtils.getErrorLogSpec(); + + final String creationTimestamp = LogUtils.formatDate(optionalLogSpec.getCreationTimestamp()); + + final String[] errorLogValues = { + creationTimestamp, + errorLogSpec.getRequestId(), + event.getThreadName(), + errorLogSpec.getServiceName(), + errorLogSpec.getPartnerName(), + errorLogSpec.getTargetEntity(), + errorLogSpec.getTargetServiceName(), + logLevelCategory != null ? logLevelCategory.name() : "", + errorLogSpec.getErrorCode() != null ? errorLogSpec.getErrorCode().toString() : "", + errorLogSpec.getErrorDescription(), + event.getFormattedMessage() + }; + + return LogUtils.createLogMessageString(errorLogValues); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/MetricLogLayout.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/MetricLogLayout.java new file mode 100644 index 0000000..509ff8f --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/MetricLogLayout.java @@ -0,0 +1,83 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.layout; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.LayoutBase; +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.spec.AppLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.MetricLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; + +/** + * Metric Log Layout generates log messages as per EELF Metric Log Specifications + * + * @author Rajiv Singla + */ +public class MetricLogLayout extends LayoutBase { + + @Override + public String doLayout(final ILoggingEvent event) { + + final AppLogSpec appLogSpec = LogUtils.getAppLogSpec(); + final LogLevelCategory logLevelCategory = LogUtils.getLogLevelCategory(); + final Class loggerClass = LogUtils.getLoggerClass(); + final OptionalLogSpec optionalLogSpec = LogUtils.getOptionalLogSpec(loggerClass, logLevelCategory); + final MetricLogSpec metricLogSpec = LogUtils.getMetricLogSpec(); + + final String beginTimestamp = LogUtils.formatDate(metricLogSpec.getBeginTimestamp()); + final String endTimestamp = LogUtils.formatDate(metricLogSpec.getEndTimestamp()); + + final String[] metricLogValues = { + beginTimestamp, + endTimestamp, + metricLogSpec.getRequestId(), + appLogSpec.getServiceInstanceID(), + event.getThreadName(), + appLogSpec.getVirtualServerName(), + metricLogSpec.getServiceName(), + metricLogSpec.getPartnerName(), + metricLogSpec.getTargetEntity(), + metricLogSpec.getTargetServiceName(), + optionalLogSpec.getStatusCode().name(), + metricLogSpec.getResponseCode().toString(), + metricLogSpec.getResponseDescription(), + appLogSpec.getInstanceUUID(), + logLevelCategory != null ? logLevelCategory.name() : "", + optionalLogSpec.getAlertSeverity().getSeverityCode(), + appLogSpec.getServerIPAddress(), + metricLogSpec.getElapsedTime().toString(), + appLogSpec.getServerFQDN(), + metricLogSpec.getClientIPAddress(), + optionalLogSpec.getClassName(), + optionalLogSpec.getUnused(), + optionalLogSpec.getProcessId(), + metricLogSpec.getTargetVirtualEntity(), + optionalLogSpec.getCustomField1(), + optionalLogSpec.getCustomField2(), + optionalLogSpec.getCustomField3(), + optionalLogSpec.getCustomField4(), + event.getFormattedMessage() + }; + + return LogUtils.createLogMessageString(metricLogValues); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/listener/LogbackStartupListener.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/listener/LogbackStartupListener.java new file mode 100644 index 0000000..b02c471 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/listener/LogbackStartupListener.java @@ -0,0 +1,128 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.listener; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.spi.LoggerContextListener; +import ch.qos.logback.core.Context; +import ch.qos.logback.core.spi.ContextAwareBase; +import ch.qos.logback.core.spi.LifeCycle; +import ch.qos.logback.core.status.InfoStatus; +import ch.qos.logback.core.status.WarnStatus; +import org.onap.dcae.utils.eelf.logger.api.info.AppLogInfo; +import org.onap.dcae.utils.eelf.logger.model.spec.AppLogSpecImpl; + + +import java.io.File; + +import static org.onap.dcae.utils.eelf.logger.logback.EELFLoggerDefaults.DEFAULT_APP_LOG_INFO; +import static org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils.APP_LOG_SPEC_KEY; +import static org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils.CUSTOM_MDC_MAP; + + +/** + * Logback Startup Listener is used to inject {@link AppLogInfo} + * + * @author Rajiv Singla + */ +public class LogbackStartupListener extends ContextAwareBase implements LoggerContextListener, LifeCycle { + + private static final String APP_LOG_INFO_KEY_IN_CONTEXT = "APP_LOG_INFO"; + private static final String CONTEXT_COMPONENT_NAME_PROPERTY_KEY = "componentName"; + private static final String CONTEXT_MODIFY_WINDOWS_LOG_PATH_PROPERTY_KEY = "modifyLogPathInWindows"; + private static final String CONTEXT_LOG_DIRECTORY_PROPERTY_KEY = "logDirectory"; + private static final String CONTEXT_DEBUG_LOG_DIRECTORY_PROPERTY_KEY = "debugLogDirectory"; + private static final String CONTEXT_APPEND_DIRECTORY_PROPERTY_KEY = "appendDirectory"; + + private boolean started = false; + + @Override + public boolean isResetResistant() { + return true; + } + + @Override + public void onStart(final LoggerContext context) { + + } + + @Override + public void onReset(final LoggerContext context) { + + } + + @Override + public void onStop(final LoggerContext context) { + + } + + @Override + public void onLevelChange(final Logger logger, final Level level) { + + } + + @Override + public void start() { + if (started) { + return; + } + + Context context = getContext(); + + CUSTOM_MDC_MAP.put(APP_LOG_SPEC_KEY, new AppLogSpecImpl(DEFAULT_APP_LOG_INFO)); + context.putObject(APP_LOG_INFO_KEY_IN_CONTEXT, DEFAULT_APP_LOG_INFO); + context.getStatusManager().add(new InfoStatus("Initialized APP LOG INFO", DEFAULT_APP_LOG_INFO)); + + // if Component name is not set derive from jar file name + if (context.getProperty(CONTEXT_COMPONENT_NAME_PROPERTY_KEY) == null) { + final String appName = + new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath()).getName(); + context.putProperty(CONTEXT_COMPONENT_NAME_PROPERTY_KEY, appName); + context.getStatusManager().add(new WarnStatus( + "No componentName Property found. Deriving it from jar name", appName)); + } + + // if modify windows log path is enabled - then append target before log directories + if (context.getProperty(CONTEXT_MODIFY_WINDOWS_LOG_PATH_PROPERTY_KEY).equalsIgnoreCase("true")) { + final String os = System.getProperty("os.name"); + if (os != null && os.startsWith("Windows")) { + final String logDirectory = context.getProperty(CONTEXT_LOG_DIRECTORY_PROPERTY_KEY); + final String debugLogDirectory = context.getProperty(CONTEXT_DEBUG_LOG_DIRECTORY_PROPERTY_KEY); + final String appendDir = context.getProperty(CONTEXT_APPEND_DIRECTORY_PROPERTY_KEY); + context.putProperty(CONTEXT_LOG_DIRECTORY_PROPERTY_KEY, appendDir + "/" + logDirectory); + context.putProperty(CONTEXT_DEBUG_LOG_DIRECTORY_PROPERTY_KEY, appendDir + "/" + debugLogDirectory); + } + } + + started = true; + } + + @Override + public void stop() { + + } + + @Override + public boolean isStarted() { + return started; + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/AuditLogImpl.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/AuditLogImpl.java new file mode 100644 index 0000000..947b4c2 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/AuditLogImpl.java @@ -0,0 +1,119 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.log.AuditLog; +import org.onap.dcae.utils.eelf.logger.api.spec.AuditLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; +import org.slf4j.Logger; + + +/** + * Audit Log Logback Implementation + * + * @author Rajiv Singla + */ +public class AuditLogImpl implements AuditLog { + + private final Logger logger; + private final Class clazz; + + public AuditLogImpl(final Logger logger, final Class clazz) { + this.logger = logger; + this.clazz = clazz; + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final AuditLogSpec + auditLogSpec, final OptionalLogSpec optionalLogSpec, final String... args) { + // if audit log spec or log level category is null throw an exception + if (auditLogSpec == null || logLevelCategory == null) { + throw new IllegalArgumentException("Audit Log Spec and Log level category must not be null"); + } + // required fields + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOG_LEVEL_CATEGORY_KEY, logLevelCategory); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.AUDIT_LOG_SPEC_KEY, auditLogSpec); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOGGER_CLASS_KEY, clazz); + // optional fields + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.OPTIONAL_LOG_SPEC_KEY, optionalLogSpec); + + // log with normalized log level category + LogUtils.logWithLogLevel(logLevelCategory, logger, LogUtils.AUDIT_LOG_MARKER, message, args); + + // clean up + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOG_LEVEL_CATEGORY_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.AUDIT_LOG_SPEC_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOGGER_CLASS_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.OPTIONAL_LOG_SPEC_KEY); + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final AuditLogSpec auditLogSpec, + final String... args) { + log(logLevelCategory, message, auditLogSpec, null, args); + } + + @Override + public void info(final String message, final AuditLogSpec auditLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.INFO, message, auditLogSpec, optionalLogSpec, args); + } + + @Override + public void info(final String message, final AuditLogSpec auditLogSpec, final String... args) { + info(message, auditLogSpec, null, args); + } + + @Override + public void warn(final String message, final AuditLogSpec auditLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.WARN, message, auditLogSpec, optionalLogSpec, args); + } + + @Override + public void warn(final String message, final AuditLogSpec auditLogSpec, final String... args) { + warn(message, auditLogSpec, null, args); + } + + @Override + public void error(final String message, final AuditLogSpec auditLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.ERROR, message, auditLogSpec, optionalLogSpec, args); + } + + @Override + public void error(final String message, final AuditLogSpec auditLogSpec, final String... args) { + error(message, auditLogSpec, null, args); + } + + @Override + public void fatal(final String message, final AuditLogSpec auditLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.FATAL, message, auditLogSpec, optionalLogSpec, args); + } + + @Override + public void fatal(final String message, final AuditLogSpec auditLogSpec, final String... args) { + fatal(message, auditLogSpec, null, args); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/DebugLogImpl.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/DebugLogImpl.java new file mode 100644 index 0000000..1e17f3b --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/DebugLogImpl.java @@ -0,0 +1,88 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.log.DebugLog; +import org.onap.dcae.utils.eelf.logger.api.spec.DebugLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; +import org.slf4j.Logger; + + +/** + * Debug Log Logback Implementation + * + * @author Rajiv Singla + */ +public class DebugLogImpl implements DebugLog { + + private final Logger logger; + private final Class clazz; + + public DebugLogImpl(final Logger logger, final Class clazz) { + this.logger = logger; + this.clazz = clazz; + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final DebugLogSpec debugLogSpec, + final OptionalLogSpec optionalLogSpec, final String... args) { + + // if log level category is null throw an exception + if (logLevelCategory == null) { + throw new IllegalArgumentException("Log level category must not be null"); + } + + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOG_LEVEL_CATEGORY_KEY, logLevelCategory); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.DEBUG_LOG_SPEC_KEY, debugLogSpec); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOGGER_CLASS_KEY, clazz); + // optional fields + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.OPTIONAL_LOG_SPEC_KEY, optionalLogSpec); + + // log with normalized log level category + LogUtils.logWithLogLevel(logLevelCategory, logger, LogUtils.DEBUG_LOG_MARKER, message, args); + + // clean up + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOG_LEVEL_CATEGORY_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.DEBUG_LOG_SPEC_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOGGER_CLASS_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.OPTIONAL_LOG_SPEC_KEY); + + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final DebugLogSpec debugLogSpec, + final String... args) { + log(logLevelCategory, message, debugLogSpec, null, args); + } + + @Override + public void debug(final String message, final DebugLogSpec debugLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.DEBUG, message, debugLogSpec, optionalLogSpec, args); + } + + @Override + public void debug(final String message, final DebugLogSpec debugLogSpec, final String... args) { + debug(message, debugLogSpec, null, args); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/EELFLoggerContextImpl.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/EELFLoggerContextImpl.java new file mode 100644 index 0000000..e5be1d8 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/EELFLoggerContextImpl.java @@ -0,0 +1,57 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + +import org.onap.dcae.utils.eelf.logger.api.log.EELFLoggerContext; +import org.onap.dcae.utils.eelf.logger.api.spec.AppLogSpec; +import org.onap.dcae.utils.eelf.logger.model.spec.AppLogSpecImpl; + +import static org.onap.dcae.utils.eelf.logger.logback.EELFLoggerDefaults.DEFAULT_APP_LOG_INFO; +import static org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils.APP_LOG_SPEC_KEY; +import static org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils.CUSTOM_MDC_MAP; + + +/** + * Default EELF Logger Context which contains EELF Specs which are usually constant for entire life cycle of the + * application + * + * @author Rajiv Singla + */ +public class EELFLoggerContextImpl implements EELFLoggerContext { + + @Override + public AppLogSpec getAppLogSpec() { + return CUSTOM_MDC_MAP.get(APP_LOG_SPEC_KEY) == null ? null : (AppLogSpec) CUSTOM_MDC_MAP.get(APP_LOG_SPEC_KEY); + } + + @Override + public void setAppLogSpec(final AppLogSpec appLogSpec) { + if (appLogSpec == null) { + CUSTOM_MDC_MAP.put(APP_LOG_SPEC_KEY, new AppLogSpecImpl(DEFAULT_APP_LOG_INFO)); + } else { + CUSTOM_MDC_MAP.put(APP_LOG_SPEC_KEY, appLogSpec); + } + } + + @Override + public boolean isInitialized() { + return CUSTOM_MDC_MAP.get(APP_LOG_SPEC_KEY) == null; + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/EELFLoggerImpl.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/EELFLoggerImpl.java new file mode 100644 index 0000000..3f1e716 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/EELFLoggerImpl.java @@ -0,0 +1,81 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + + +import org.onap.dcae.utils.eelf.logger.api.log.AuditLog; +import org.onap.dcae.utils.eelf.logger.api.log.DebugLog; +import org.onap.dcae.utils.eelf.logger.api.log.EELFLogger; +import org.onap.dcae.utils.eelf.logger.api.log.EELFLoggerContext; +import org.onap.dcae.utils.eelf.logger.api.log.ErrorLog; +import org.onap.dcae.utils.eelf.logger.api.log.MetricLog; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * EELF Logger Logback Implementation + * + * @author Rajiv Singla + */ +public class EELFLoggerImpl implements EELFLogger { + + private Logger logger; + private Class clazz; + + public EELFLoggerImpl() { + // no arg constructor required for Service Loader discovery + } + + public EELFLoggerImpl(final Class clazz) { + logger = LoggerFactory.getLogger(clazz); + this.clazz = clazz; + } + + + @Override + public AuditLog auditLog() { + return new AuditLogImpl(logger, clazz); + } + + @Override + public MetricLog metricLog() { + return new MetricLogImpl(logger, clazz); + } + + @Override + public ErrorLog errorLog() { + return new ErrorLogImpl(logger, clazz); + } + + @Override + public DebugLog debugLog() { + return new DebugLogImpl(logger, clazz); + } + + @Override + public EELFLoggerContext loggingContext() { + return new EELFLoggerContextImpl(); + } + + @Override + public String toString() { + return "EELF LOGBACK IMP"; + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/ErrorLogImpl.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/ErrorLogImpl.java new file mode 100644 index 0000000..5d8f272 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/ErrorLogImpl.java @@ -0,0 +1,98 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.log.ErrorLog; +import org.onap.dcae.utils.eelf.logger.api.spec.ErrorLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; +import org.slf4j.Logger; + + +/** + * Error Log Logback Implementation + * + * @author Rajiv Singla + */ +public class ErrorLogImpl implements ErrorLog { + + private final Logger logger; + private final Class clazz; + + public ErrorLogImpl(final Logger logger, final Class clazz) { + this.logger = logger; + this.clazz = clazz; + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final ErrorLogSpec errorLogSpec, + final OptionalLogSpec optionalLogSpec, final String... args) { + + // if error log spec or log level category is null throw an exception + if (errorLogSpec == null || logLevelCategory == null) { + throw new IllegalArgumentException("Error Log Spec and Log level category must not be null"); + } + + // required fields + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOG_LEVEL_CATEGORY_KEY, logLevelCategory); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.ERROR_LOG_SPEC_KEY, errorLogSpec); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOGGER_CLASS_KEY, clazz); + // optional fields + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.OPTIONAL_LOG_SPEC_KEY, optionalLogSpec); + + // log with normalized log level category + LogUtils.logWithLogLevel(logLevelCategory, logger, LogUtils.ERROR_LOG_MARKER, message, args); + + // clean up + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOG_LEVEL_CATEGORY_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.ERROR_LOG_SPEC_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOGGER_CLASS_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.OPTIONAL_LOG_SPEC_KEY); + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final ErrorLogSpec errorLogSpec, + final String... args) { + log(logLevelCategory, message, errorLogSpec, null, args); + } + + @Override + public void error(final String message, final ErrorLogSpec errorLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.ERROR, message, errorLogSpec, null, args); + } + + @Override + public void error(final String message, final ErrorLogSpec errorLogSpec, final String... args) { + error(message, errorLogSpec, null, args); + } + + @Override + public void warn(final String message, final ErrorLogSpec errorLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.WARN, message, errorLogSpec, null, args); + } + + @Override + public void warn(final String message, final ErrorLogSpec errorLogSpec, final String... args) { + warn(message, errorLogSpec, null, args); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/MetricLogImpl.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/MetricLogImpl.java new file mode 100644 index 0000000..5857835 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/MetricLogImpl.java @@ -0,0 +1,120 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.log.MetricLog; +import org.onap.dcae.utils.eelf.logger.api.spec.MetricLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; +import org.slf4j.Logger; + +/** + * Metric Log Logback Implementation + * + * @author Rajiv Singla + */ +public class MetricLogImpl implements MetricLog { + + private final Logger logger; + private final Class clazz; + + public MetricLogImpl(final Logger logger, final Class clazz) { + this.logger = logger; + this.clazz = clazz; + } + + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final MetricLogSpec metricLogSpec, + final OptionalLogSpec optionalLogSpec, final String... args) { + + // if metric log spec or log level category is null throw an exception + if (metricLogSpec == null || logLevelCategory == null) { + throw new IllegalArgumentException("Metric Log Spec and Log level category must not be null"); + } + + // required fields + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOG_LEVEL_CATEGORY_KEY, logLevelCategory); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.METRIC_LOG_SPEC_KEY, metricLogSpec); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOGGER_CLASS_KEY, clazz); + // optional fields + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.OPTIONAL_LOG_SPEC_KEY, optionalLogSpec); + + // log with normalized log level category + LogUtils.logWithLogLevel(logLevelCategory, logger, LogUtils.METRIC_LOG_MARKER, message, args); + + // clean up + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOG_LEVEL_CATEGORY_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.METRIC_LOG_SPEC_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOGGER_CLASS_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.OPTIONAL_LOG_SPEC_KEY); + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final MetricLogSpec metricLogSpec, + final String... args) { + log(logLevelCategory, message, metricLogSpec, null, args); + } + + @Override + public void info(final String message, final MetricLogSpec metricLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.INFO, message, metricLogSpec, optionalLogSpec, args); + } + + @Override + public void info(final String message, final MetricLogSpec metricLogSpec, final String... args) { + log(LogLevelCategory.INFO, message, metricLogSpec, args); + } + + @Override + public void warn(final String message, final MetricLogSpec metricLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.WARN, message, metricLogSpec, optionalLogSpec, args); + } + + @Override + public void warn(final String message, final MetricLogSpec metricLogSpec, final String... args) { + warn(message, metricLogSpec, null, args); + } + + @Override + public void error(final String message, final MetricLogSpec metricLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.ERROR, message, metricLogSpec, optionalLogSpec, args); + } + + @Override + public void error(final String message, final MetricLogSpec metricLogSpec, final String... args) { + error(message, metricLogSpec, null, args); + } + + @Override + public void fatal(final String message, final MetricLogSpec metricLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.FATAL, message, metricLogSpec, optionalLogSpec, args); + } + + @Override + public void fatal(final String message, final MetricLogSpec metricLogSpec, final String... args) { + fatal(message, metricLogSpec, null, args); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/CompositePropertyResolver.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/CompositePropertyResolver.java new file mode 100644 index 0000000..e5f1bc1 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/CompositePropertyResolver.java @@ -0,0 +1,53 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.resolver; + +import java.util.Arrays; +import java.util.List; + +/** + * A composite property resolver can look under different resolvers in order of given property resolvers + * + * @author Rajiv Singla + */ +public class CompositePropertyResolver implements PropertyResolver { + + private static final long serialVersionUID = 1L; + + private final List propertyResolvers; + + public CompositePropertyResolver(PropertyResolver... propertyResolvers) { + this.propertyResolvers = Arrays.asList(propertyResolvers); + } + + @Override + public String resolve(final List propertyNames) { + // resolver property in given resolvers in the same order they are defined + for (PropertyResolver propertyResolver : propertyResolvers) { + final String propertyValue = propertyResolver.resolve(propertyNames); + if (propertyValue != null) { + return propertyValue; + } + } + + return null; + } + +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/EnvironmentPropertyResolver.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/EnvironmentPropertyResolver.java new file mode 100644 index 0000000..8f3d59f --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/EnvironmentPropertyResolver.java @@ -0,0 +1,46 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.resolver; + +import java.util.List; + +/** + * Looks up Property values inside HOST environment variables + * + * @author Rajiv Singla + */ +public class EnvironmentPropertyResolver implements PropertyResolver { + + private static final long serialVersionUID = 1L; + + @Override + public String resolve(final List propertyNames) { + + // check if system environment variables have property names set + for (final String propertyName : propertyNames) { + final String propertyValue = System.getenv(propertyName); + if (propertyValue != null) { + return propertyValue; + } + } + + return null; + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/PropertyResolver.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/PropertyResolver.java new file mode 100644 index 0000000..758de61 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/PropertyResolver.java @@ -0,0 +1,41 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.resolver; + +import java.io.Serializable; +import java.util.List; + +/** + * A resolver is used to resolve properties + * + * @author Rajiv Singla + */ +public interface PropertyResolver extends Serializable { + + /** + * Returns resolved property value + * + * @param propertyNames names under which property can be found + * + * @return property value + */ + String resolve(List propertyNames); + +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/SystemPropertyResolver.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/SystemPropertyResolver.java new file mode 100644 index 0000000..674b00b --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/SystemPropertyResolver.java @@ -0,0 +1,59 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.resolver; + +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * Resolve System Properties passed in by -DpropertyName=propertyValue when invoking + * via java command line arguments + * + * @author Rajiv Singla + */ +public class SystemPropertyResolver implements PropertyResolver { + + private static final long serialVersionUID = 1L; + + @Override + public String resolve(final List propertyNames) { + + // Get all system Properties + final Properties systemProperties = System.getProperties(); + + for (Map.Entry systemEntries : systemProperties.entrySet()) { + + if (systemEntries.getKey() instanceof String) { + final String systemKey = (String) systemEntries.getKey(); + + // if system properties contain any of the property names - ignoring case then return its value + for (String propertyName : propertyNames) { + if (propertyName.equalsIgnoreCase(systemKey)) { + return (String) systemEntries.getValue(); + } + } + + } + } + + return null; + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/utils/LogUtils.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/utils/LogUtils.java new file mode 100644 index 0000000..f5c558b --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/utils/LogUtils.java @@ -0,0 +1,590 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.utils; + +import ch.qos.logback.core.CoreConstants; +import org.onap.dcae.utils.eelf.logger.api.info.AppLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.info.NagiosAlertLevel; +import org.onap.dcae.utils.eelf.logger.api.info.RequestIdLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.RequestStatusCode; +import org.onap.dcae.utils.eelf.logger.api.spec.AppLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.AuditLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.DebugLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.ErrorLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.MetricLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.EELFLoggerDefaults; +import org.onap.dcae.utils.eelf.logger.logback.resolver.CompositePropertyResolver; +import org.onap.dcae.utils.eelf.logger.logback.resolver.EnvironmentPropertyResolver; +import org.onap.dcae.utils.eelf.logger.logback.resolver.SystemPropertyResolver; +import org.onap.dcae.utils.eelf.logger.model.info.AppLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.CodeLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.MessageLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.RequestIdLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.RequestTimingLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.AppLogSpecImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.AuditLogSpecImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.DebugLogSpecImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.ErrorLogSpecImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.MetricLogSpecImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.OptionalLogSpecImpl; +import org.slf4j.Logger; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; +import java.util.UUID; + + + +/** + * Contains various logging utility methods + * + * @author Rajiv Singla + */ +public abstract class LogUtils { + + private static final String LOG_MESSAGE_DELIMITER = "|"; + private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; + private static final String DATE_TIMEZONE = "UTC"; + // property resolver which looks up system property and the environment properties + private static final CompositePropertyResolver COMPOSITE_PROPERTY_RESOLVER = + new CompositePropertyResolver(new SystemPropertyResolver(), new EnvironmentPropertyResolver()); + + // Custom MDC Map Keys + public static final String APP_LOG_SPEC_KEY = "APP_LOG_SPEC"; + public static final String AUDIT_LOG_SPEC_KEY = "AUDIT_LOG_SPEC"; + public static final String METRIC_LOG_SPEC_KEY = "METRIC_LOG_SPEC"; + public static final String ERROR_LOG_SPEC_KEY = "ERROR_LOG_SPEC"; + public static final String DEBUG_LOG_SPEC_KEY = "DEBUG_LOG_SPEC"; + public static final String OPTIONAL_LOG_SPEC_KEY = "OPTIONAL_LOG_SPEC"; + public static final String LOG_LEVEL_CATEGORY_KEY = "LOG_LEVEL_CATEGORY"; + public static final String LOGGER_CLASS_KEY = "LOGGER_CLASS_KEY"; + + // markers + public static final Marker AUDIT_LOG_MARKER = MarkerFactory.getMarker("AUDIT_LOG"); + public static final Marker METRIC_LOG_MARKER = MarkerFactory.getMarker("METRIC_LOG"); + public static final Marker ERROR_LOG_MARKER = MarkerFactory.getMarker("ERROR_LOG"); + public static final Marker DEBUG_LOG_MARKER = MarkerFactory.getMarker("DEBUG_LOG"); + + + public static final Map CUSTOM_MDC_MAP = new ThreadLocal>() { + @Override + protected Map initialValue() { + return new HashMap<>(); + } + }.get(); + + public static final ThreadLocal SIMPLE_DATE_FORMAT = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT); + simpleDateFormat.setTimeZone(TimeZone.getTimeZone(DATE_TIMEZONE)); + return simpleDateFormat; + } + }; + + + private LogUtils() { + // private constructor + } + + + /** + * Logs eomp message with normalized log level category + * + * @param logLevelCategory ecomp log level category + * @param logger logback logger + * @param marker logback marker + * @param message log message + * @param args log message arguments for interpolation + */ + public static void logWithLogLevel(final LogLevelCategory logLevelCategory, + final Logger logger, final Marker marker, + final String message, final String... args) { + switch (logLevelCategory) { + case DEBUG: + logger.debug(marker, message, args); + break; + case INFO: + logger.info(marker, message, args); + break; + case WARN: + logger.warn(marker, message, args); + break; + default: + // fatal log level is treated as error also as logback does not have fatal level + logger.error(marker, message, args); + } + } + + + /** + * Returns value for {@link AppLogSpec}. If no {@link AppLogSpec} is defined a default app log spec is passed + * + * @return app log spec + */ + public static AppLogSpec getAppLogSpec() { + final AppLogSpec appLogSpec = getCustomMapValue(APP_LOG_SPEC_KEY, AppLogSpec.class); + return appLogSpec == null ? new AppLogSpecImpl(EELFLoggerDefaults.DEFAULT_APP_LOG_INFO) : appLogSpec; + } + + /** + * Populate default values of {@link OptionalLogSpec} if not present + * + * @param loggerClass logger class + * @param logLevelCategory log level category + * + * @return optional log spec with default values if not present + */ + public static OptionalLogSpec getOptionalLogSpec(final Class loggerClass, final LogLevelCategory + logLevelCategory) { + + OptionalLogSpecImpl optionalLogSpec = + getCustomMapValue(OPTIONAL_LOG_SPEC_KEY, OptionalLogSpecImpl.class); + + if (optionalLogSpec != null) { + // if message log info is empty populate default values + if (optionalLogSpec.getMessageLogInfo() == null || + optionalLogSpec.getCreationTimestamp() == null && optionalLogSpec.getAlertSeverity() == null && + optionalLogSpec.getStatusCode() == null) { + optionalLogSpec = optionalLogSpec.withMessageLogInfo(createDefaultMessageLogInfo(logLevelCategory)); + } + // if code log info is empty populate default values + if (optionalLogSpec.getCodeLogInfo() == null || + optionalLogSpec.getClassName() == null && optionalLogSpec.getThreadId() == null) { + optionalLogSpec = optionalLogSpec.withCodeLogInfo(createDefaultCodeLogInfo(loggerClass)); + } + // if custom fields log info is empty populate default values + if (optionalLogSpec.getCustomFieldsLogInfo() == null) { + optionalLogSpec = + optionalLogSpec.withCustomFieldsLogInfo(EELFLoggerDefaults.DEFAULT_CUSTOM_FIELDS_LOG_INFO); + } + // if misc fields log info is empty populate default values + if (optionalLogSpec.getMiscLogInfo() == null) { + optionalLogSpec = optionalLogSpec.withMiscLogInfo(EELFLoggerDefaults.DEFAULT_MISC_LOG_INFO); + } + } else { + // optional log spec is null so create new optional log spec + optionalLogSpec = createDefaultOptionalLogSpec(loggerClass, logLevelCategory); + } + + return optionalLogSpec; + } + + + /** + * Formats given date in ISO 8601 format + * + * @param date Date object + * + * @return formatted date string + */ + public static String formatDate(final Date date) { + if (date == null) { + return ""; + } + return SIMPLE_DATE_FORMAT.get().format(date); + } + + /** + * Creates log message string + * + * @param logValues log message values + * + * @return log message string + */ + public static String createLogMessageString(final String[] logValues) { + final StringBuffer stringBuffer = new StringBuffer(512); + for (int i = 0; i < logValues.length; i++) { + final String logValue = logValues[i]; + stringBuffer.append(logValue != null ? logValue : ""); + if (i != logValues.length - 1) { + stringBuffer.append(LOG_MESSAGE_DELIMITER); + } + } + stringBuffer.append(CoreConstants.LINE_SEPARATOR); + return stringBuffer.toString(); + } + + /** + * Gets custom MDC value from Custom MDC Map for give key. Returns null if no value can be found + * + * @param key MDC Map key + * @param clazz expected value class type + * @param class type + * + * @return value inside Custom MDC Map + */ + private static T getCustomMapValue(final String key, final Class clazz) { + final Object value = CUSTOM_MDC_MAP.get(key); + if (value != null) { + return clazz.cast(value); + } + return null; + } + + + /** + * Get current Metric log spec from the custom MDC map and populates default values if not present + * + * @return Metric log spec + */ + public static MetricLogSpec getMetricLogSpec() { + MetricLogSpecImpl metricLogSpec = getCustomMapValue(METRIC_LOG_SPEC_KEY, MetricLogSpecImpl.class); + + if (metricLogSpec != null) { + if (metricLogSpec.getRequestIdLogInfo() == null || metricLogSpec.getRequestId() == null) { + metricLogSpec = metricLogSpec.withRequestIdLogInfo(createNewRequestIdLogInfo()); + } + if (metricLogSpec.getServiceLogInfo() == null) { + metricLogSpec = metricLogSpec.withServiceLogInfo(EELFLoggerDefaults.DEFAULT_SERVICE_LOG_INFO); + } + if (metricLogSpec.getRequestTimingLogInfo() == null || metricLogSpec.getBeginTimestamp() == null || + metricLogSpec.getEndTimestamp() == null) { + metricLogSpec = + metricLogSpec.withRequestTimingLogInfo(EELFLoggerDefaults.DEFAULT_REQUEST_TIMING_LOG_INFO); + } + if (metricLogSpec.getResponseLogInfo() == null) { + metricLogSpec = metricLogSpec.withResponseLogInfo(EELFLoggerDefaults.DEFAULT_RESPONSE_LOG_INFO); + } + final Date beginTimestamp = metricLogSpec.getBeginTimestamp(); + final Date endTimestamp = metricLogSpec.getEndTimestamp(); + final Long elapsedTime = metricLogSpec.getElapsedTime(); + if (endTimestamp != null && beginTimestamp != null && elapsedTime == null) { + final RequestTimingLogInfoImpl requestTimingLogInfo = + new RequestTimingLogInfoImpl(beginTimestamp, endTimestamp, + endTimestamp.getTime() - beginTimestamp.getTime()); + metricLogSpec = metricLogSpec.withRequestTimingLogInfo(requestTimingLogInfo); + } + if (metricLogSpec.getTargetServiceLogInfo() == null) { + metricLogSpec = + metricLogSpec.withTargetServiceLogInfo(EELFLoggerDefaults.DEFAULT_TARGET_SERVICE_LOG_INFO); + } + } else { + throw new IllegalArgumentException("Metric Log Spec must not be null"); + } + + return metricLogSpec; + } + + /** + * Get current Debug log spec from the custom MDC map and populates default values if not present + * + * @return Debug log spec + */ + public static DebugLogSpec getDebugLogSpec() { + final DebugLogSpecImpl debugLogSpec = getCustomMapValue(DEBUG_LOG_SPEC_KEY, DebugLogSpecImpl.class); + if (debugLogSpec == null || debugLogSpec.getRequestIdLogInfo() == null || debugLogSpec.getRequestId() == null) { + return new DebugLogSpecImpl(createNewRequestIdLogInfo()); + } + return debugLogSpec; + } + + /** + * Get current Error log spec from the custom MDC map and populates default values if not present + * + * @return Error log spec + */ + public static ErrorLogSpec getErrorLogSpec() { + ErrorLogSpecImpl errorLogSpec = getCustomMapValue(ERROR_LOG_SPEC_KEY, ErrorLogSpecImpl.class); + if (errorLogSpec != null) { + + if (errorLogSpec.getRequestIdLogInfo() == null || errorLogSpec.getRequestId() == null) { + errorLogSpec = errorLogSpec.withRequestIdLogInfo(createNewRequestIdLogInfo()); + } + if (errorLogSpec.getServiceLogInfo() == null) { + errorLogSpec = errorLogSpec.withServiceLogInfo(EELFLoggerDefaults.DEFAULT_SERVICE_LOG_INFO); + } + if (errorLogSpec.getTargetServiceLogInfo() == null) { + errorLogSpec = + errorLogSpec.withTargetServiceLogInfo(EELFLoggerDefaults.DEFAULT_TARGET_SERVICE_LOG_INFO); + } + if (errorLogSpec.getErrorLogInfo() == null) { + errorLogSpec = errorLogSpec.withErrorLogInfo(EELFLoggerDefaults.DEFAULT_ERROR_LOG_INFO); + } + + } else { + throw new IllegalArgumentException("Error Log Spec cannot be null"); + } + return errorLogSpec; + } + + + /** + * Get current Audit log spec from the custom MDC map and populates default values if not present + * + * @return Audit log spec + */ + public static AuditLogSpec getAuditLogSpec() { + AuditLogSpecImpl auditLogSpec = getCustomMapValue(AUDIT_LOG_SPEC_KEY, AuditLogSpecImpl.class); + if (auditLogSpec != null) { + if (auditLogSpec.getServiceLogInfo() == null) { + auditLogSpec = auditLogSpec.withServiceLogInfo(EELFLoggerDefaults.DEFAULT_SERVICE_LOG_INFO); + } + if (auditLogSpec.getRequestIdLogInfo() == null || auditLogSpec.getRequestId() == null) { + auditLogSpec = auditLogSpec.withRequestIdLogInfo(createNewRequestIdLogInfo()); + } + if (auditLogSpec.getResponseLogInfo() == null) { + auditLogSpec = auditLogSpec.withResponseLogInfo(EELFLoggerDefaults.DEFAULT_RESPONSE_LOG_INFO); + } + + if (auditLogSpec.getRequestTimingLogInfo() == null || auditLogSpec.getBeginTimestamp() == null || + auditLogSpec.getEndTimestamp() == null) { + auditLogSpec = + auditLogSpec.withRequestTimingLogInfo(EELFLoggerDefaults.DEFAULT_REQUEST_TIMING_LOG_INFO); + } + final Date beginTimestamp = auditLogSpec.getBeginTimestamp(); + final Date endTimestamp = auditLogSpec.getEndTimestamp(); + final Long elapsedTime = auditLogSpec.getElapsedTime(); + if (endTimestamp != null && beginTimestamp != null && elapsedTime == null) { + final RequestTimingLogInfoImpl requestTimingLogInfo = + new RequestTimingLogInfoImpl(beginTimestamp, endTimestamp, + endTimestamp.getTime() - beginTimestamp.getTime()); + auditLogSpec = auditLogSpec.withRequestTimingLogInfo(requestTimingLogInfo); + } + + } else { + throw new IllegalArgumentException("Audit Log Spec cannot be null"); + } + + return auditLogSpec; + } + + + private static RequestIdLogInfo createNewRequestIdLogInfo() { + return new RequestIdLogInfoImpl(UUID.randomUUID().toString()); + } + + /** + * Return Log Level Category from MDC Map + * + * @return log level category + */ + public static Class getLoggerClass() { + final Class loggerClass = getCustomMapValue(LOGGER_CLASS_KEY, Class.class); + // logger class must always be non null + if (loggerClass != null) { + return loggerClass; + } + return LogUtils.class.getClass(); + } + + + /** + * Return Log Level Category from MDC Map + * + * @return log level category + */ + public static LogLevelCategory getLogLevelCategory() { + final LogLevelCategory logLevelCategory = getCustomMapValue(LOG_LEVEL_CATEGORY_KEY, LogLevelCategory.class); + if (logLevelCategory != null) { + return logLevelCategory; + } + return LogLevelCategory.ERROR; + } + + /** + * Creates Default Optional Log spec + * + * @param loggerClass logger class name + * @param logLevelCategory Log leve category + * + * @return default optional log spec + */ + private static OptionalLogSpecImpl createDefaultOptionalLogSpec(final Class loggerClass, + final LogLevelCategory logLevelCategory) { + return new OptionalLogSpecImpl(createDefaultMessageLogInfo(logLevelCategory), + createDefaultCodeLogInfo(loggerClass), EELFLoggerDefaults.DEFAULT_CUSTOM_FIELDS_LOG_INFO, + EELFLoggerDefaults.DEFAULT_MISC_LOG_INFO); + } + + + /** + * Creates Default Code Log Info + * + * @param loggerClass logger class name + * + * @return default code log info + */ + private static CodeLogInfoImpl createDefaultCodeLogInfo(final Class loggerClass) { + // thread id can be extracted from the framework + return new CodeLogInfoImpl(null, loggerClass != null ? loggerClass.getName() : ""); + } + + + /** + * Creates Default Message Log Info + * + * @param logLevelCategory Log leve category + * + * @return default message log info + */ + private static MessageLogInfoImpl createDefaultMessageLogInfo(final LogLevelCategory logLevelCategory) { + return new MessageLogInfoImpl(new Date(), + getStatusCode(logLevelCategory), + getNagiosAlertLevel(logLevelCategory)); + } + + + /** + * Creates Default App Log Spec + * + * @return default APP log Spec + */ + public static AppLogInfoImpl createDefaultAppLogInfo() { + final String serviceInstanceId = + resolveProperty(null, AppLogInfo.Defaults.DEFAULT_SERVICE_INSTANCE_ID, + "SERVICE_NAME", "ServiceInstanceId", "SERVICE_INSTANCE_ID"); + final String instanceUUID = + resolveProperty(null, AppLogInfo.Defaults.DEFAULT_INSTANCE_UUID, + "InstanceUUID", "INSTANCE_UUID"); + final String virtualServerName = + resolveProperty(null, AppLogInfo.Defaults.DEFAULT_VIRTUAL_SERVER_NAME, + "VirtualServerName", "VIRTUAL_SERVER_NAME"); + final String serverIPAddress = getHostIPAddress() != null ? + getHostIPAddress() : AppLogInfo.Defaults.DEFAULT_SERVER_IP_ADDRESS; + final String serverFQDN = getHostName() != null ? getHostName() : AppLogInfo.Defaults.DEFAULT_SERVER_FQDN; + return new AppLogInfoImpl(serviceInstanceId, instanceUUID, virtualServerName, serverIPAddress, serverFQDN); + } + + + /** + * Returns status code based on log level category + * + * @param logLevelCategory log level category + * + * @return request status code as string based on log level category + */ + private static RequestStatusCode getStatusCode(final LogLevelCategory logLevelCategory) { + if (logLevelCategory == LogLevelCategory.DEBUG || logLevelCategory == LogLevelCategory.INFO || + logLevelCategory == LogLevelCategory.WARN) { + return RequestStatusCode.COMPLETE; + } else { + return RequestStatusCode.ERROR; + } + } + + /** + * Returns nagios Alert level based on log level category + * + * @param logLevelCategory log level category + * + * @return nagios alert level + */ + private static NagiosAlertLevel getNagiosAlertLevel(final LogLevelCategory logLevelCategory) { + switch (logLevelCategory) { + case DEBUG: + return NagiosAlertLevel.OK; + case INFO: + return NagiosAlertLevel.OK; + case WARN: + return NagiosAlertLevel.WARNING; + case ERROR: + return NagiosAlertLevel.CRITICAL; + case FATAL: + return NagiosAlertLevel.CRITICAL; + default: + return NagiosAlertLevel.UNKNOWN; + } + } + + /** + * Resolves property value if not present + * + * @param userPassedValue user passed property value + * @param defaultValue default value if no value is found after resolving the property + * @param propertyNames property names + * + * @return resolved property value + */ + private static String resolveProperty( + final String userPassedValue, final String defaultValue, final String... propertyNames) { + // if user passed is present return that value + if (userPassedValue != null) { + return userPassedValue; + } + // resolve it using composite resolver + final String resolveProperty = resolveProperty(Arrays.asList(propertyNames)); + return resolveProperty != null ? resolveProperty : defaultValue; + } + + /** + * Resolves property values in different places + * + * @param propertyNames property Names + * + * @return property Value + */ + private static String resolveProperty(final List propertyNames) { + return COMPOSITE_PROPERTY_RESOLVER.resolve(propertyNames); + } + + + /** + * Determine host IP Address + * + * @return host ip address + */ + private static String getHostIPAddress() { + final InetAddress inetAddress = getInetAddress(); + if (inetAddress != null) { + return inetAddress.getHostAddress(); + } + return null; + } + + /** + * Determines fully qualified host name + * + * @return fully qualified host name + */ + private static String getHostName() { + final InetAddress inetAddress = getInetAddress(); + if (inetAddress != null) { + return inetAddress.getCanonicalHostName(); + } + return null; + } + + /** + * Fetches Inet Address + * + * @return Inet Address + */ + private static InetAddress getInetAddress() { + try { + return InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + return null; + } + } + + +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/resources/META-INF/services/org.onap.dcae.utils.eelf.logger.api.log.EELFLogger b/eelf-logger/eelf-logger-logback-impl/src/main/resources/META-INF/services/org.onap.dcae.utils.eelf.logger.api.log.EELFLogger new file mode 100644 index 0000000..d7d5c71 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/resources/META-INF/services/org.onap.dcae.utils.eelf.logger.api.log.EELFLogger @@ -0,0 +1,20 @@ +# +# ================================================================================ +# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# 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. +# ============LICENSE_END========================================================= +# +# + +org.onap.dcae.utils.eelf.logger.logback.log.EELFLoggerImpl diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-async-appenders.xml b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-async-appenders.xml new file mode 100644 index 0000000..e2e93e4 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-async-appenders.xml @@ -0,0 +1,55 @@ + + + + + + + + ${queueSize} + ${maxFlushTime} + + + + + ${queueSize} + ${maxFlushTime} + + + + + ${queueSize} + ${maxFlushTime} + + + + + ${queueSize} + ${maxFlushTime} + + + + + + diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-defaults.xml b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-defaults.xml new file mode 100644 index 0000000..f9bb078 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-defaults.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-logback.xml b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-logback.xml new file mode 100644 index 0000000..7e08eb2 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-logback.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-optional-appenders.xml b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-optional-appenders.xml new file mode 100644 index 0000000..fb7ec7f --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-optional-appenders.xml @@ -0,0 +1,68 @@ + + + + + + + + + DEBUG_LOG + ACCEPT + DENY + + + ${debugLogDirectory}/${debugLogName}.log + + + ${logDirectory}/${debugLogName}.%i.log.zip + ${minFileIndex} + ${maxFileIndex} + + + + ${maxFileSize} + + + + + + + + + + + + + + METRIC_LOG,AUDIT_LOG,ERROR_LOG,DEBUG_LOG + ACCEPT + DENY + + + + + + + + diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-required-appenders.xml b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-required-appenders.xml new file mode 100644 index 0000000..72f1a5d --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-required-appenders.xml @@ -0,0 +1,112 @@ + + + + + + + + + AUDIT_LOG + ACCEPT + DENY + + + ${logDirectory}/${auditLogName}.log + + + ${logDirectory}/${auditLogName}.%i.log.zip + ${minFileIndex} + ${maxFileIndex} + + + + ${maxFileSize} + + + + + + + + + + + + + + METRIC_LOG + ACCEPT + DENY + + + ${logDirectory}/${metricLogName}.log + + + ${logDirectory}/${metricLogName}.%i.log.zip + ${minFileIndex} + ${maxFileIndex} + + + + ${maxFileSize} + + + + + + + + + + + + + + ERROR_LOG + ACCEPT + DENY + + + ${logDirectory}/${errorLogName}.log + + + ${logDirectory}/${errorLogName}.%i.log.zip + ${minFileIndex} + ${maxFileIndex} + + + + ${maxFileSize} + + + + + + + + + + -- cgit 1.2.3-korg