Interface MetricTimeSeriesRepository

All Superinterfaces:
org.springframework.data.repository.Repository<MetricRecordEntity,Long>

@Repository public interface MetricTimeSeriesRepository extends org.springframework.data.repository.Repository<MetricRecordEntity,Long>
Spring Data JPA repository providing time-series and aggregated metric queries for the chart and anomaly endpoints.

Contains native SQL queries that aggregate MetricRecordEntity records into 30-second buckets for system-wide chart rendering, and JPQL queries for per-service historical data and recent anomaly retrieval. Uses JOIN FETCH on the service relationship where the controller subsequently accesses service.name to prevent lazy-loading exceptions.

Author:
Nazar Montytskyi
  • Method Details

    • findRecentByService

      @Query("SELECT m FROM MetricRecordEntity m\nWHERE m.service.id = :serviceId\n AND m.recordedAt >= :from\n AND m.source = :source\nORDER BY m.recordedAt ASC\n") List<MetricRecordEntity> findRecentByService(@Param("serviceId") Long serviceId, @Param("from") LocalDateTime from, @Param("source") MetricRecordEntity.MetricSource source, org.springframework.data.domain.Pageable pageable)
    • findRecentAnomalies

      @Query("SELECT m FROM MetricRecordEntity m\nJOIN FETCH m.service\nWHERE m.anomaly = true\n AND m.recordedAt >= :from\nORDER BY m.recordedAt DESC\n") List<MetricRecordEntity> findRecentAnomalies(@Param("from") LocalDateTime from, org.springframework.data.domain.Pageable pageable)
    • findSystemAggregated

      @Query(value="SELECT\n TO_TIMESTAMP(FLOOR(EXTRACT(EPOCH FROM recorded_at) / 30) * 30)::timestamp AS bucket,\n AVG(response_time_ms) AS avg_rt,\n MAX(response_time_ms) AS max_rt,\n AVG(cpu_usage) AS avg_cpu,\n AVG(heap_used_mb) AS avg_heap,\n COUNT(DISTINCT CASE WHEN status = 'UP' THEN service_id END) AS up_cnt,\n COUNT(DISTINCT CASE WHEN status = 'DOWN' THEN service_id END) AS down_cnt,\n COUNT(DISTINCT CASE WHEN status = 'DEGRADED' THEN service_id END) AS deg_cnt,\n COUNT(DISTINCT CASE WHEN anomaly = true THEN service_id END) AS anomaly_cnt\nFROM metric_records\nWHERE recorded_at >= :from\nGROUP BY FLOOR(EXTRACT(EPOCH FROM recorded_at) / 30)\nORDER BY bucket ASC\nLIMIT :lim\n", nativeQuery=true) List<Object[]> findSystemAggregated(@Param("from") LocalDateTime from, @Param("lim") int lim)