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

no.digipost.monitoring.certificate.CertificateExpiryMetrics Maven / Gradle / Ivy

/*
 * Copyright (C) Posten Norge AS
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package no.digipost.monitoring.certificate;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.binder.MeterBinder;

import java.security.KeyStoreException;
import java.security.cert.X509Certificate;
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

import static java.time.temporal.ChronoUnit.DAYS;
import static java.util.Arrays.asList;

/**
 * Micrometer {@link MeterBinder} registering gauges for Java key store certificates.
 *
 * 

* Each certificate gauge keeps track of seconds until certificate expiry. It * also has some useful tags such as keystore alias, X509 certificate fields as * issuer, subject, notBefore and notAfter. */ public final class CertificateExpiryMetrics implements MeterBinder { public static final int DEFAULT_DAYS_TO_EXPIRY_WARN_THRESHOLD = 60; private final List monitoredX509Certificates; private final Clock clock; private final int daysToExpiryWarnThreshold; /** * Create a new meter binder. * * @param monitoredX509Certificates key store containing certificates to monitor. */ public CertificateExpiryMetrics(List monitoredX509Certificates, Clock clock) { this(monitoredX509Certificates, clock, DEFAULT_DAYS_TO_EXPIRY_WARN_THRESHOLD); } /** * Create a new meter binder setting days to warn * * @param monitoredX509Certificates key store containing certificates to monitor. * @param clock The time of the server */ public CertificateExpiryMetrics(List monitoredX509Certificates, Clock clock, int daysToExpiryWarnThreshold) { this.clock = clock; this.daysToExpiryWarnThreshold = daysToExpiryWarnThreshold; this.monitoredX509Certificates = Objects.requireNonNull(monitoredX509Certificates, "monitoredX509Certificates can not be null"); } @Override public void bindTo(MeterRegistry registry) { try { for (MonitoredX509Certificate cert : monitoredX509Certificates) { registerGauge(registry, cert); } } catch (KeyStoreException e) { throw new IllegalStateException(e); } } private void registerGauge(MeterRegistry registry, MonitoredX509Certificate monitoredX509Certificate) throws KeyStoreException { X509Certificate cert = monitoredX509Certificate.certificate; List tags = asList( Tag.of("alias", monitoredX509Certificate.description.orElse(cert.getSerialNumber().toString())), Tag.of("issuer", cert.getIssuerX500Principal().getName()), Tag.of("subject", cert.getSubjectX500Principal().getName()), Tag.of("notAfter", cert.getNotAfter().toString()), Tag.of("notBefore", cert.getNotBefore().toString()) ); registry.gauge( "cert_expiry", tags, cert, c -> Duration.between(Instant.now(clock), c.getNotAfter().toInstant()).getSeconds() ); registry.gauge("certificates_status", tags, cert, c -> { final long daysToExpiry = DAYS.between(LocalDate.now(clock), LocalDateTime.ofInstant(c.getNotAfter().toInstant(), clock.getZone()).toLocalDate()); if (daysToExpiry > this.daysToExpiryWarnThreshold) { return ValidityStatus.VALID.code(); } else if (daysToExpiry <= 0) { return ValidityStatus.INVALID.code(); } else { return ValidityStatus.EXPIRING.code(); } } ); } enum ValidityStatus { INVALID(-1), EXPIRING(0), VALID(1); private int i; ValidityStatus(int i) { this.i = i; } public int code() { return i; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy