aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas <>2022-12-07 10:54:35 +0100
committerThomas <>2022-12-07 10:54:35 +0100
commit30f1ff7b45f3d05147329323751516ed8114c9f2 (patch)
tree5808fc3e5f3c8f26e2d25bbd2ec224d4086dd382
parentd4811a0890a72198abae5b4a8bfa756ada1fc3f6 (diff)
downloadNational_eIDAS_Gateway-30f1ff7b45f3d05147329323751516ed8114c9f2.tar.gz
National_eIDAS_Gateway-30f1ff7b45f3d05147329323751516ed8114c9f2.tar.bz2
National_eIDAS_Gateway-30f1ff7b45f3d05147329323751516ed8114c9f2.zip
feat(proxyservice): add additional JSON based statistic logger
-rw-r--r--basicConfig/ms-proxyservice/logback_config.xml18
-rw-r--r--ms_specific_proxyservice/src/main/java/at/asitplus/eidas/specific/proxy/logger/AdvancedStatisicLogger.java171
-rw-r--r--ms_specific_proxyservice/src/main/java/at/asitplus/eidas/specific/proxy/logger/MultipleStatisticLogger.java68
-rw-r--r--ms_specific_proxyservice/src/main/resources/specific_eIDAS_proxy.beans.xml2
4 files changed, 258 insertions, 1 deletions
diff --git a/basicConfig/ms-proxyservice/logback_config.xml b/basicConfig/ms-proxyservice/logback_config.xml
index d2bf5d85..a7e1552b 100644
--- a/basicConfig/ms-proxyservice/logback_config.xml
+++ b/basicConfig/ms-proxyservice/logback_config.xml
@@ -52,6 +52,21 @@
</triggeringPolicy>
</appender>
+ <appender name="statisticJson" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender-->
+ <File>${catalina.base}/logs/eidas-ms-statistic_proxyservice.log</File>
+ <encoder>
+ <pattern>%m%n</pattern>
+ </encoder>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <maxIndex>9999</maxIndex>
+ <FileNamePattern>${catalina.base}/logs/eidas-ms-statistic_proxyservice.%i</FileNamePattern>
+ </rollingPolicy>
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <MaxFileSize>10000KB</MaxFileSize>
+ </triggeringPolicy>
+ </appender>
+
<appender name="stdout" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender-->
<File>${catalina.base}/logs/console.log</File>
@@ -72,6 +87,9 @@
<logger name="at.asitplus.eidas.specific.core.logger.StatisticLogger" additivity="false" level="info">
<appender-ref ref="statistic"/>
</logger>
+ <logger name="at.asitplus.eidas.specific.proxy.logger.AdvancedStatisicLogger" additivity="false" level="info">
+ <appender-ref ref="statisticJson"/>
+ </logger>
<logger name="at.asitplus.eidas.specific.core.logger.RevisionLogger" level="info">
<appender-ref ref="reversion"/>
</logger>
diff --git a/ms_specific_proxyservice/src/main/java/at/asitplus/eidas/specific/proxy/logger/AdvancedStatisicLogger.java b/ms_specific_proxyservice/src/main/java/at/asitplus/eidas/specific/proxy/logger/AdvancedStatisicLogger.java
new file mode 100644
index 00000000..fda988a6
--- /dev/null
+++ b/ms_specific_proxyservice/src/main/java/at/asitplus/eidas/specific/proxy/logger/AdvancedStatisicLogger.java
@@ -0,0 +1,171 @@
+package at.asitplus.eidas.specific.proxy.logger;
+
+import java.time.LocalDateTime;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.IStatusMessenger;
+import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.idp.IEidAuthData;
+import at.gv.egiz.eaaf.core.api.logging.IStatisticLogger;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Extended statistic logger that use a JSON based data model.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class AdvancedStatisicLogger implements IStatisticLogger {
+
+ private static final String DATEFORMATER = "yyyy.MM.dd-HH:mm:ss";
+ private static final String DEFAULT_NO_IDP_ID = "no idpId available";
+
+ private static final ObjectMapper mapper = new ObjectMapper();
+
+ private final IStatusMessenger messageService;
+
+ /**
+ * Build a JSON based statistic logger that uses error messages from a specific source.
+ *
+ * @param source i18n message source
+ */
+ public AdvancedStatisicLogger(IStatusMessenger source) {
+ this.messageService = source;
+
+ }
+
+ @Override
+ public void logSuccessOperation(IRequest protocolRequest, IAuthData authData, boolean isSsoSession) {
+ final StatisticLogEntry entry = buildCoreEntry(protocolRequest);
+ entry.setSuccess(SuccessEntry.builder()
+ .spSector(protocolRequest.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier())
+ .withMandates(selectMandateProcessType(authData))
+ .build());
+ writeEntryToLog(entry);
+
+ }
+
+ @Override
+ public void logErrorOperation(Throwable throwable) {
+ log.trace("Advanced statistic logger only logs on SP level");
+
+ }
+
+ @Override
+ public void logErrorOperation(Throwable throwable, IRequest errorRequest) {
+ final StatisticLogEntry entry = buildCoreEntry(errorRequest);
+ entry.setError(new ErrorEntry(messageService.getResponseErrorCode(throwable), throwable.getMessage()));
+ writeEntryToLog(entry);
+
+ }
+
+ @Override
+ public void internalTesting() throws Exception {
+ log.trace("Not implemented for a File-based logger");
+
+ }
+
+ private StatisticLogEntry buildCoreEntry(IRequest pendingRequest) {
+ return new StatisticLogEntry(
+ LocalDateTime.now(),
+ pendingRequest.getUniqueTransactionIdentifier(),
+ pendingRequest.getServiceProviderConfiguration() != null
+ && pendingRequest.getServiceProviderConfiguration().getUniqueIdentifier() != null
+ ? pendingRequest.getServiceProviderConfiguration().getUniqueIdentifier() : DEFAULT_NO_IDP_ID);
+
+ }
+
+ private MandateProcess selectMandateProcessType(IAuthData authData) {
+ if (authData instanceof IEidAuthData && ((IEidAuthData)authData).isUseMandate()) {
+ return authData.getGenericData(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, String.class) != null
+ ? MandateProcess.FOR_LEGAL_PERSON : MandateProcess.FOR_NATURAL_PERSON;
+
+ } else {
+ return MandateProcess.NONE;
+
+ }
+ }
+
+ private void writeEntryToLog(StatisticLogEntry entry) {
+ try {
+ log.info(mapper.writeValueAsString(entry));
+
+ } catch (final JsonProcessingException e) {
+ log.error("Can NOT generate statistic entry for logging", e);
+
+ }
+ }
+
+ public enum MandateProcess { NONE, FOR_NATURAL_PERSON, FOR_LEGAL_PERSON }
+
+ @Getter
+ @Setter
+ @RequiredArgsConstructor
+ @JsonInclude(Include.NON_NULL)
+ private static class StatisticLogEntry {
+
+ @JsonSerialize(using = LocalDateTimeSerializer.class)
+ @JsonDeserialize(using = LocalDateTimeDeserializer.class)
+ @JsonFormat(pattern = DATEFORMATER)
+ @JsonProperty("timestamp")
+ private final LocalDateTime timestamp;
+
+ @JsonProperty("txId")
+ private final String transactionId;
+
+ @JsonProperty("entityId")
+ private final String idpEntityId;
+
+ @JsonProperty("success")
+ private SuccessEntry success;
+
+ @JsonProperty("error")
+ private ErrorEntry error;
+
+ }
+
+ @Getter
+ @Setter
+ @Builder
+ @JsonInclude(Include.NON_NULL)
+ private static class SuccessEntry {
+
+ @JsonProperty("spSector")
+ private final String spSector;
+
+ @JsonProperty("withMandates")
+ private final MandateProcess withMandates;
+
+ }
+
+ @Getter
+ @Setter
+ @RequiredArgsConstructor
+ private static class ErrorEntry {
+
+ @JsonProperty("code")
+ private final String errorCode;
+
+ @JsonProperty("msg")
+ private final String errorMessage;
+
+ }
+
+}
diff --git a/ms_specific_proxyservice/src/main/java/at/asitplus/eidas/specific/proxy/logger/MultipleStatisticLogger.java b/ms_specific_proxyservice/src/main/java/at/asitplus/eidas/specific/proxy/logger/MultipleStatisticLogger.java
new file mode 100644
index 00000000..bd771fb2
--- /dev/null
+++ b/ms_specific_proxyservice/src/main/java/at/asitplus/eidas/specific/proxy/logger/MultipleStatisticLogger.java
@@ -0,0 +1,68 @@
+package at.asitplus.eidas.specific.proxy.logger;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.google.common.collect.Sets;
+
+import at.asitplus.eidas.specific.core.logger.StatisticLogger;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.IStatusMessenger;
+import at.gv.egiz.eaaf.core.api.idp.IAuthData;
+import at.gv.egiz.eaaf.core.api.logging.IStatisticLogger;
+
+/**
+ * {@link IStatisticLogger} implementation that can log into more than one internal {@link IStatisticLogger}.
+ *
+ * @author tlenz
+ *
+ */
+public class MultipleStatisticLogger implements IStatisticLogger {
+
+ private final Set<IStatisticLogger> internalLoggers;
+
+ /**
+ * Build a statistic logger that logs into {@link StatisticLogger} and {@link AdvancedStatisicLogger}.
+ *
+ * @param messageService i18n message-source implementation.
+ */
+ public MultipleStatisticLogger(@Autowired IStatusMessenger messageService) {
+ internalLoggers = Collections.unmodifiableSet(
+ Sets.newHashSet(
+ new StatisticLogger(),
+ new AdvancedStatisicLogger(messageService)));
+
+ }
+
+
+
+ @Override
+ public void logSuccessOperation(IRequest protocolRequest, IAuthData authData, boolean isSsoSession) {
+ internalLoggers.parallelStream()
+ .forEach(el -> el.logSuccessOperation(protocolRequest, authData, isSsoSession));
+
+ }
+
+ @Override
+ public void logErrorOperation(Throwable throwable) {
+ internalLoggers.parallelStream().forEach(el -> el.logErrorOperation(throwable));
+
+ }
+
+ @Override
+ public void logErrorOperation(Throwable throwable, IRequest errorRequest) {
+ internalLoggers.parallelStream().forEach(el -> el.logErrorOperation(throwable, errorRequest));
+
+ }
+
+ @Override
+ public void internalTesting() throws Exception {
+ for (IStatisticLogger el : internalLoggers) {
+ el.internalTesting();
+
+ }
+ }
+
+}
diff --git a/ms_specific_proxyservice/src/main/resources/specific_eIDAS_proxy.beans.xml b/ms_specific_proxyservice/src/main/resources/specific_eIDAS_proxy.beans.xml
index 646b851c..3893600e 100644
--- a/ms_specific_proxyservice/src/main/resources/specific_eIDAS_proxy.beans.xml
+++ b/ms_specific_proxyservice/src/main/resources/specific_eIDAS_proxy.beans.xml
@@ -14,7 +14,7 @@
<import resource="specific_eIDAS_core.beans.xml"/>
<bean id="eidasStatisticLogger"
- class="at.asitplus.eidas.specific.core.logger.StatisticLogger" />
+ class="at.asitplus.eidas.specific.proxy.logger.MultipleStatisticLogger" />
<bean id="ProxyAuthenticationDataBuilder"
class="at.asitplus.eidas.specific.proxy.builder.ProxyAuthenticationDataBuilder" />