diff options
| author | Thomas <> | 2022-10-21 14:32:29 +0200 | 
|---|---|---|
| committer | Thomas <> | 2022-10-21 14:32:29 +0200 | 
| commit | 2e92a85fac99d5f2366197bbd9d24436efa21c22 (patch) | |
| tree | ee9cc7a35a0a7a04041fe53f7cccfcb3ae07efad /ms_specific_connector/src | |
| parent | 7798a53d11d5a57ca8abde0ab24d9c42b8bb4d9b (diff) | |
| download | National_eIDAS_Gateway-2e92a85fac99d5f2366197bbd9d24436efa21c22.tar.gz National_eIDAS_Gateway-2e92a85fac99d5f2366197bbd9d24436efa21c22.tar.bz2 National_eIDAS_Gateway-2e92a85fac99d5f2366197bbd9d24436efa21c22.zip | |
feat(connector): add JSON based statistic logger
Diffstat (limited to 'ms_specific_connector/src')
2 files changed, 245 insertions, 0 deletions
| diff --git a/ms_specific_connector/src/main/java/at/asitplus/eidas/specific/core/logger/AdvancedStatisicLogger.java b/ms_specific_connector/src/main/java/at/asitplus/eidas/specific/core/logger/AdvancedStatisicLogger.java new file mode 100644 index 00000000..f3c43579 --- /dev/null +++ b/ms_specific_connector/src/main/java/at/asitplus/eidas/specific/core/logger/AdvancedStatisicLogger.java @@ -0,0 +1,178 @@ +package at.asitplus.eidas.specific.core.logger; + +import java.time.LocalDateTime; + +import org.apache.commons.lang3.StringUtils; + +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.asitplus.eidas.specific.core.MsEidasNodeConstants; +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; +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+z"; +  private static final String DEFAULT_NO_IDP_ID = "no idpId available"; +  private static final String DEFAULT_NO_SP_ID = "no appId 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()) +        .citizenCountryCode(authData.getCiticenCountryCode()) +        .matchingMethod(extractMatchingState(protocolRequest.getRawData(MsEidasNodeConstants.DATA_MATCHING_STATE))) +        .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 errorRequest) { +    Object appId = errorRequest.getRawData(MsEidasNodeConstants.DATA_REQUESTERID); +    return new StatisticLogEntry( +        LocalDateTime.now(), +        errorRequest.getUniqueTransactionIdentifier(), +        errorRequest.getServiceProviderConfiguration() != null  +            && errorRequest.getServiceProviderConfiguration().getUniqueIdentifier() != null  +          ? errorRequest.getServiceProviderConfiguration().getUniqueIdentifier() : DEFAULT_NO_IDP_ID, +        appId instanceof String && StringUtils.isNotEmpty((String)appId) +            ? (String)appId : DEFAULT_NO_SP_ID);   +     +  } +   +  private String extractMatchingState(Object state) { +    return state != null ? state.toString() : MsEidasNodeConstants.MatchingStates.NO_REQUIRED.toString(); +     +  } +   +  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); + +    } +  } +   +   +  @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("unique-sp-id") +    private final String uniqueId; + +    @JsonProperty("success") +    private SuccessEntry success; + +    @JsonProperty("error") +    private ErrorEntry error; + +  } + +  @Getter +  @Setter +  @Builder +  @RequiredArgsConstructor +  @JsonInclude(Include.NON_NULL) +  private static class SuccessEntry { + +    @JsonProperty("spSector") +    private final String spSector; +     +    @JsonProperty("ccc") +    private final String citizenCountryCode; +     +    @JsonProperty("finalMatchingMethod") +    private final String matchingMethod; + +         +  } + +  @Getter +  @Setter +  @RequiredArgsConstructor +  private static class ErrorEntry { + +    @JsonProperty("code") +    private final String errorCode; +     +    @JsonProperty("msg") +    private final String errorMessage; + +  } + +} diff --git a/ms_specific_connector/src/main/java/at/asitplus/eidas/specific/core/logger/MultipleStatisticLogger.java b/ms_specific_connector/src/main/java/at/asitplus/eidas/specific/core/logger/MultipleStatisticLogger.java new file mode 100644 index 00000000..008a5691 --- /dev/null +++ b/ms_specific_connector/src/main/java/at/asitplus/eidas/specific/core/logger/MultipleStatisticLogger.java @@ -0,0 +1,67 @@ +package at.asitplus.eidas.specific.core.logger; + +import java.util.Collections; +import java.util.Set; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.google.common.collect.Sets; + +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(); +       +    } +  } + +} | 
