From ca49a1e36dc801c136c960c5a74fabaf4f83bec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=89=E1=85=B5=E1=86=AB=E1=84=92=E1=85=B4=E1=84=89?= =?UTF-8?q?=E1=85=A5=E1=86=BC?= Date: Sat, 18 Oct 2025 15:24:54 +0900 Subject: [PATCH 1/5] =?UTF-8?q?JPA=20dependency=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exporter/build.gradle.kts | 13 +++ .../src/main/resources/application.properties | 1 - exporter/src/main/resources/application.yml | 24 +++++ exporter/src/main/resources/schema.sql | 91 +++++++++++++++++++ 4 files changed, 128 insertions(+), 1 deletion(-) delete mode 100644 exporter/src/main/resources/application.properties create mode 100644 exporter/src/main/resources/application.yml create mode 100644 exporter/src/main/resources/schema.sql diff --git a/exporter/build.gradle.kts b/exporter/build.gradle.kts index 9b07490..087c4c3 100644 --- a/exporter/build.gradle.kts +++ b/exporter/build.gradle.kts @@ -1,6 +1,7 @@ plugins { kotlin("jvm") kotlin("plugin.spring") + kotlin("plugin.jpa") version "1.9.24" id("org.springframework.boot") id("io.spring.dependency-management") } @@ -11,10 +12,16 @@ java { } } +repositories { + mavenCentral() +} + dependencies { implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-actuator") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") + implementation("org.springframework.boot:spring-boot-starter-data-jpa") + runtimeOnly("com.mysql:mysql-connector-j") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("io.micrometer:micrometer-core") implementation("com.zaxxer:HikariCP") @@ -42,3 +49,9 @@ tasks.withType { enabled = false } } + +allOpen { + annotation("jakarta.persistence.Entity") + annotation("jakarta.persistence.MappedSuperclass") + annotation("jakarta.persistence.Embeddable") +} diff --git a/exporter/src/main/resources/application.properties b/exporter/src/main/resources/application.properties deleted file mode 100644 index c7bde5c..0000000 --- a/exporter/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name=monilab-exporter-ex diff --git a/exporter/src/main/resources/application.yml b/exporter/src/main/resources/application.yml new file mode 100644 index 0000000..e860c0d --- /dev/null +++ b/exporter/src/main/resources/application.yml @@ -0,0 +1,24 @@ +spring: + application: + name: monilab-exporter-ex + main: + banner-mode: off + jpa: + database-platform: org.hibernate.dialect.MySQL5InnoDBDialect + show-sql: true + hibernate: + ddl-auto: update + properties: + hibernate: + default_batch_fetch_size: 1000 + dialect: org.hibernate.dialect.MySQLDialect + + datasource: + url: jdbc:mysql://${DB_URL:localhost:3306}/${DB_NAME:monilab}?useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true + username: ${DB_USER:root} + password: ${DB_PASSWORD:12345} + driver-class-name: com.mysql.cj.jdbc.Driver + + sql: + init: + mode: always diff --git a/exporter/src/main/resources/schema.sql b/exporter/src/main/resources/schema.sql new file mode 100644 index 0000000..81465eb --- /dev/null +++ b/exporter/src/main/resources/schema.sql @@ -0,0 +1,91 @@ +CREATE TABLE IF NOT EXISTS tb_metric_memory ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + label VARCHAR(10) NOT NULL, + used BIGINT NOT NULL, + max BIGINT NOT NULL, + committed BIGINT NOT NULL, + eden BIGINT NOT NULL, + survivor BIGINT NOT NULL, + old BIGINT NOT NULL, + buffer_pool_used BIGINT NOT NULL, + max_direct_memory_size BIGINT NOT NULL +); + +CREATE TABLE IF NOT EXISTS tb_metric_gc ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + label VARCHAR(10) NOT NULL, + count BIGINT NOT NULL, + time BIGINT NOT NULL, + pause BIGINT NOT NULL, + allocation_rate DOUBLE NOT NULL, + live_data_size BIGINT NOT NULL, + gc_strategy VARCHAR(255) NOT NULL +); + +CREATE TABLE IF NOT EXISTS tb_metric_threads ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + label VARCHAR(10) NOT NULL, + count INT NOT NULL, + daemon_count INT NOT NULL, + peak_count INT NOT NULL, + deadlocked_count INT NOT NULL, + cpu_time BIGINT NOT NULL, + states TEXT NOT NULL +); + + + +CREATE TABLE IF NOT EXISTS tb_metric_cpu ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + label VARCHAR(10) NOT NULL, + process_usage DOUBLE NOT NULL, + system_usage DOUBLE NOT NULL, + uptime BIGINT NOT NULL, + start_time BIGINT NOT NULL, + load_average DOUBLE NOT NULL, + open_fds BIGINT NOT NULL +); + +CREATE TABLE IF NOT EXISTS tb_metric_network ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + label VARCHAR(10) NOT NULL, + bytes_sent BIGINT NOT NULL, + bytes_received BIGINT NOT NULL, + tcp_connections INT NOT NULL, + tcp_established INT NOT NULL, + open_sockets INT NOT NULL, + prefer_ipv4 BOOLEAN NOT NULL +); + +CREATE TABLE IF NOT EXISTS tb_metric_class_loading ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + label VARCHAR(10) NOT NULL, + loaded INT NOT NULL, + unloaded BIGINT NOT NULL, + code_cache_used BIGINT NOT NULL, + code_cache_max BIGINT NOT NULL, + compilation_time BIGINT NOT NULL, + reserved_code_cache_size BIGINT NOT NULL +); + +CREATE TABLE IF NOT EXISTS tb_metric_class_loading ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + label VARCHAR(10) NOT NULL, + loaded INT NOT NULL, + unloaded BIGINT NOT NULL, + code_cache_used BIGINT NOT NULL, + code_cache_max BIGINT NOT NULL, + compilation_time BIGINT NOT NULL, + reserved_code_cache_size BIGINT NOT NULL +); + +CREATE TABLE IF NOT EXISTS tb_metric_application ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + label VARCHAR(10) NOT NULL, + http_requests_count BIGINT NOT NULL, + http_latency DOUBLE NOT NULL, + db_connections_active INT NOT NULL, + db_connections_max INT NOT NULL, + queue_tasks_pending INT NOT NULL, + custom_metrics TEXT NOT NULL +); From c0890b9cf4e52e435a8915a67fc2a89b827beba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=89=E1=85=B5=E1=86=AB=E1=84=92=E1=85=B4=E1=84=89?= =?UTF-8?q?=E1=85=A5=E1=86=BC?= Date: Sat, 18 Oct 2025 15:25:15 +0900 Subject: [PATCH 2/5] JPA Entity init --- .../model/ApplicationEntity.kt | 35 ++++++++++++++++ .../model/ClassLoadingInfoEntity.kt | 34 ++++++++++++++++ .../lab/monilabexporterex/model/CpuEntity.kt | 34 ++++++++++++++++ .../lab/monilabexporterex/model/GcEntity.kt | 34 ++++++++++++++++ .../monilabexporterex/model/MemoryEntity.kt | 40 +++++++++++++++++++ .../monilabexporterex/model/NetworkEntity.kt | 34 ++++++++++++++++ .../monilabexporterex/model/ThreadsEntity.kt | 35 ++++++++++++++++ 7 files changed, 246 insertions(+) create mode 100644 exporter/src/main/kotlin/lab/monilabexporterex/model/ApplicationEntity.kt create mode 100644 exporter/src/main/kotlin/lab/monilabexporterex/model/ClassLoadingInfoEntity.kt create mode 100644 exporter/src/main/kotlin/lab/monilabexporterex/model/CpuEntity.kt create mode 100644 exporter/src/main/kotlin/lab/monilabexporterex/model/GcEntity.kt create mode 100644 exporter/src/main/kotlin/lab/monilabexporterex/model/MemoryEntity.kt create mode 100644 exporter/src/main/kotlin/lab/monilabexporterex/model/NetworkEntity.kt create mode 100644 exporter/src/main/kotlin/lab/monilabexporterex/model/ThreadsEntity.kt diff --git a/exporter/src/main/kotlin/lab/monilabexporterex/model/ApplicationEntity.kt b/exporter/src/main/kotlin/lab/monilabexporterex/model/ApplicationEntity.kt new file mode 100644 index 0000000..ee3e45c --- /dev/null +++ b/exporter/src/main/kotlin/lab/monilabexporterex/model/ApplicationEntity.kt @@ -0,0 +1,35 @@ +package lab.monilabexporterex.model + +import jakarta.persistence.* + +@Entity +@Table(name = "tb_metric_application") +class ApplicationEntity( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + val id: Long = 0, + + @Enumerated(EnumType.STRING) + @Column(name = "label", nullable = false, length = 10) + val label: Label, + + @Column(name = "http_requests_count", nullable = false) + val httpRequestsCount: Long, + + @Column(name = "http_latency", nullable = false) + val httpLatency: Double, + + @Column(name = "db_connections_active", nullable = false) + val dbConnectionsActive: Int, + + @Column(name = "db_connections_max", nullable = false) + val dbConnectionsMax: Int, + + @Column(name = "queue_tasks_pending", nullable = false) + val queueTasksPending: Int, + + @Lob + @Column(name = "custom_metrics", columnDefinition = "TEXT", nullable = false) + val customMetrics: String, +) diff --git a/exporter/src/main/kotlin/lab/monilabexporterex/model/ClassLoadingInfoEntity.kt b/exporter/src/main/kotlin/lab/monilabexporterex/model/ClassLoadingInfoEntity.kt new file mode 100644 index 0000000..c31d840 --- /dev/null +++ b/exporter/src/main/kotlin/lab/monilabexporterex/model/ClassLoadingInfoEntity.kt @@ -0,0 +1,34 @@ +package lab.monilabexporterex.model + +import jakarta.persistence.* + +@Entity +@Table(name = "tb_metric_class_loading") +class ClassLoadingInfoEntity( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + val id: Long = 0, + + @Enumerated(EnumType.STRING) + @Column(name = "label", nullable = false, length = 10) + val label: Label, + + @Column(name = "loaded", nullable = false) + val loaded: Int, + + @Column(name = "unloaded", nullable = false) + val unloaded: Long, + + @Column(name = "code_cache_used", nullable = false) + val codeCacheUsed: Long, + + @Column(name = "code_cache_max", nullable = false) + val codeCacheMax: Long, + + @Column(name = "compilation_time", nullable = false) + val compilationTime: Long, + + @Column(name = "reserved_code_cache_size", nullable = false) + val reservedCodeCacheSize: Long, +) diff --git a/exporter/src/main/kotlin/lab/monilabexporterex/model/CpuEntity.kt b/exporter/src/main/kotlin/lab/monilabexporterex/model/CpuEntity.kt new file mode 100644 index 0000000..08b6a84 --- /dev/null +++ b/exporter/src/main/kotlin/lab/monilabexporterex/model/CpuEntity.kt @@ -0,0 +1,34 @@ +package lab.monilabexporterex.model + +import jakarta.persistence.* + +@Entity +@Table(name = "tb_metric_cpu") +class CpuEntity( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + val id: Long = 0, + + @Enumerated(EnumType.STRING) + @Column(name = "label", nullable = false, length = 10) + val label: Label, + + @Column(name = "process_usage", nullable = false) + val processUsage: Double, + + @Column(name = "system_usage", nullable = false) + val systemUsage: Double, + + @Column(name = "uptime", nullable = false) + val uptime: Long, + + @Column(name = "start_time", nullable = false) + val startTime: Long, + + @Column(name = "load_average", nullable = false) + val loadAverage: Double, + + @Column(name = "open_fds", nullable = false) + val openFds: Long, +) diff --git a/exporter/src/main/kotlin/lab/monilabexporterex/model/GcEntity.kt b/exporter/src/main/kotlin/lab/monilabexporterex/model/GcEntity.kt new file mode 100644 index 0000000..8603b21 --- /dev/null +++ b/exporter/src/main/kotlin/lab/monilabexporterex/model/GcEntity.kt @@ -0,0 +1,34 @@ +package lab.monilabexporterex.model + +import jakarta.persistence.* + +@Entity +@Table(name = "tb_metric_gc") +class GcEntity( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + val id: Long = 0, + + @Enumerated(EnumType.STRING) + @Column(name = "label", nullable = false, length = 10) + val label: Label, + + @Column(name = "count", nullable = false) + val count: Long, + + @Column(name = "time", nullable = false) + val time: Long, + + @Column(name = "pause", nullable = false) + val pause: Long, + + @Column(name = "allocation_rate", nullable = false) + val allocationRate: Double, + + @Column(name = "live_data_size", nullable = false) + val liveDataSize: Long, + + @Column(name = "gc_strategy", nullable = false) + val gcStrategy: String, +) diff --git a/exporter/src/main/kotlin/lab/monilabexporterex/model/MemoryEntity.kt b/exporter/src/main/kotlin/lab/monilabexporterex/model/MemoryEntity.kt new file mode 100644 index 0000000..924c13f --- /dev/null +++ b/exporter/src/main/kotlin/lab/monilabexporterex/model/MemoryEntity.kt @@ -0,0 +1,40 @@ +package lab.monilabexporterex.model + +import jakarta.persistence.* + +@Entity +@Table(name = "tb_metric_memory") +class MemoryEntity( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + val id: Long = 0, + + @Enumerated(EnumType.STRING) + @Column(name = "label", nullable = false) + val label: Label, + + @Column(name = "used", nullable = false) + val used: Long, + + @Column(name = "max", nullable = false) + val max: Long, + + @Column(name = "committed", nullable = false) + val committed: Long, + + @Column(name = "eden", nullable = false) + val eden: Long, + + @Column(name = "survivor", nullable = false) + val survivor: Long, + + @Column(name = "old", nullable = false) + val old: Long, + + @Column(name = "buffer_pool_used", nullable = false) + val bufferPoolUsed: Long, + + @Column(name = "max_direct_memory_size", nullable = false) + val maxDirectMemorySize: Long, +) diff --git a/exporter/src/main/kotlin/lab/monilabexporterex/model/NetworkEntity.kt b/exporter/src/main/kotlin/lab/monilabexporterex/model/NetworkEntity.kt new file mode 100644 index 0000000..31d4c12 --- /dev/null +++ b/exporter/src/main/kotlin/lab/monilabexporterex/model/NetworkEntity.kt @@ -0,0 +1,34 @@ +package lab.monilabexporterex.model + +import jakarta.persistence.* + +@Entity +@Table(name = "tb_metric_network") +class NetworkEntity( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + val id: Long = 0, + + @Enumerated(EnumType.STRING) + @Column(name = "label", nullable = false, length = 10) + val label: Label, + + @Column(name = "bytes_sent", nullable = false) + val bytesSent: Long, + + @Column(name = "bytes_received", nullable = false) + val bytesReceived: Long, + + @Column(name = "tcp_connections", nullable = false) + val tcpConnections: Int, + + @Column(name = "tcp_established", nullable = false) + val tcpEstablished: Int, + + @Column(name = "open_sockets", nullable = false) + val openSockets: Int, + + @Column(name = "prefer_ipv4", nullable = false) + val preferIPv4: Boolean, +) diff --git a/exporter/src/main/kotlin/lab/monilabexporterex/model/ThreadsEntity.kt b/exporter/src/main/kotlin/lab/monilabexporterex/model/ThreadsEntity.kt new file mode 100644 index 0000000..ca8ec50 --- /dev/null +++ b/exporter/src/main/kotlin/lab/monilabexporterex/model/ThreadsEntity.kt @@ -0,0 +1,35 @@ +package lab.monilabexporterex.model + +import jakarta.persistence.* + +@Entity +@Table(name = "tb_metric_threads") +class ThreadsEntity( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + val id: Long = 0, + + @Enumerated(EnumType.STRING) + @Column(name = "label", nullable = false, length = 10) + val label: Label, + + @Column(name = "count", nullable = false) + val count: Int, + + @Column(name = "daemon_count", nullable = false) + val daemonCount: Int, + + @Column(name = "peak_count", nullable = false) + val peakCount: Int, + + @Column(name = "deadlocked_count", nullable = false) + val deadlockedCount: Int, + + @Column(name = "cpu_time", nullable = false) + val cpuTime: Long, + + @Lob + @Column(name = "states", columnDefinition = "TEXT", nullable = false) + val states: String, +) From 7aad1285af3566275bc3bfd8417ca15059239605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=89=E1=85=B5=E1=86=AB=E1=84=92=E1=85=B4=E1=84=89?= =?UTF-8?q?=E1=85=A5=E1=86=BC?= Date: Sat, 18 Oct 2025 15:25:51 +0900 Subject: [PATCH 3/5] =?UTF-8?q?Mapper,=20Repository=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../monilabexporterex/api/dto/metric_dto.kt | 12 ++ .../lab/monilabexporterex/model/Label.kt | 5 + .../model/mapper/MetricMapper.kt | 178 ++++++++++++++++++ .../repository/MetricJpaRepository.kt | 26 +++ 4 files changed, 221 insertions(+) create mode 100644 exporter/src/main/kotlin/lab/monilabexporterex/api/dto/metric_dto.kt create mode 100644 exporter/src/main/kotlin/lab/monilabexporterex/model/Label.kt create mode 100644 exporter/src/main/kotlin/lab/monilabexporterex/model/mapper/MetricMapper.kt create mode 100644 exporter/src/main/kotlin/lab/monilabexporterex/repository/MetricJpaRepository.kt diff --git a/exporter/src/main/kotlin/lab/monilabexporterex/api/dto/metric_dto.kt b/exporter/src/main/kotlin/lab/monilabexporterex/api/dto/metric_dto.kt new file mode 100644 index 0000000..41ec423 --- /dev/null +++ b/exporter/src/main/kotlin/lab/monilabexporterex/api/dto/metric_dto.kt @@ -0,0 +1,12 @@ +package lab.monilabexporterex.api.dto + +data class GcMetricResponse( + val id: Long, + val label: String, + val count: Long, + val time: Long, + val pause: Long, + val allocationRate: Double, + val liveDataSize: Long, + val gcStrategy: String, +) diff --git a/exporter/src/main/kotlin/lab/monilabexporterex/model/Label.kt b/exporter/src/main/kotlin/lab/monilabexporterex/model/Label.kt new file mode 100644 index 0000000..66292c9 --- /dev/null +++ b/exporter/src/main/kotlin/lab/monilabexporterex/model/Label.kt @@ -0,0 +1,5 @@ +package lab.monilabexporterex.model + +enum class Label { + TEST, TRAIN +} diff --git a/exporter/src/main/kotlin/lab/monilabexporterex/model/mapper/MetricMapper.kt b/exporter/src/main/kotlin/lab/monilabexporterex/model/mapper/MetricMapper.kt new file mode 100644 index 0000000..2d70b05 --- /dev/null +++ b/exporter/src/main/kotlin/lab/monilabexporterex/model/mapper/MetricMapper.kt @@ -0,0 +1,178 @@ +package lab.monilabexporterex.mapper + +import lab.monilabexporterex.exporter.data.JvmMonitoringData +import lab.monilabexporterex.model.* + +object JvmMonitoringMapper { + + fun toEntity(data: JvmMonitoringData.Memory, label: Label): MemoryEntity = + MemoryEntity( + label = label, + used = data.used, + max = data.max, + committed = data.committed, + eden = data.eden, + survivor = data.survivor, + old = data.old, + bufferPoolUsed = data.bufferPoolUsed, + maxDirectMemorySize = data.maxDirectMemorySize + ) + + fun toData(entity: MemoryEntity): JvmMonitoringData.Memory = + JvmMonitoringData.Memory( + used = entity.used, + max = entity.max, + committed = entity.committed, + eden = entity.eden, + survivor = entity.survivor, + old = entity.old, + bufferPoolUsed = entity.bufferPoolUsed, + maxDirectMemorySize = entity.maxDirectMemorySize + ) + + fun toEntity(data: JvmMonitoringData.Gc, label: Label): GcEntity = + GcEntity( + label = label, + count = data.count, + time = data.time, + pause = data.pause, + allocationRate = data.allocationRate, + liveDataSize = data.liveDataSize, + gcStrategy = data.gcStrategy + ) + + fun toData(entity: GcEntity): JvmMonitoringData.Gc = + JvmMonitoringData.Gc( + count = entity.count, + time = entity.time, + pause = entity.pause, + allocationRate = entity.allocationRate, + liveDataSize = entity.liveDataSize, + gcStrategy = entity.gcStrategy + ) + + fun toEntity(data: JvmMonitoringData.Threads, label: Label): ThreadsEntity = + ThreadsEntity( + label = label, + count = data.count, + daemonCount = data.daemonCount, + peakCount = data.peakCount, + deadlockedCount = data.deadlockedCount, + cpuTime = data.cpuTime, + states = data.states.toString() + ) + + fun toData(entity: ThreadsEntity): JvmMonitoringData.Threads = + JvmMonitoringData.Threads( + count = entity.count, + daemonCount = entity.daemonCount, + peakCount = entity.peakCount, + deadlockedCount = entity.deadlockedCount, + cpuTime = entity.cpuTime, + states = parseStates(entity.states) + ) + + private fun parseStates(json: String): Map { + return json + .removePrefix("{").removeSuffix("}") + .split(",") + .mapNotNull { + val (k, v) = it.split("=") + k.trim() to v.trim().toInt() + }.toMap() + } + + fun toEntity(data: JvmMonitoringData.Cpu, label: Label): CpuEntity = + CpuEntity( + label = label, + processUsage = data.processUsage, + systemUsage = data.systemUsage, + uptime = data.uptime, + startTime = data.startTime, + loadAverage = data.loadAverage, + openFds = data.openFds + ) + + fun toData(entity: CpuEntity): JvmMonitoringData.Cpu = + JvmMonitoringData.Cpu( + processUsage = entity.processUsage, + systemUsage = entity.systemUsage, + uptime = entity.uptime, + startTime = entity.startTime, + loadAverage = entity.loadAverage, + openFds = entity.openFds + ) + + fun toEntity(data: JvmMonitoringData.Network, label: Label): NetworkEntity = + NetworkEntity( + label = label, + bytesSent = data.bytesSent, + bytesReceived = data.bytesReceived, + tcpConnections = data.tcpConnections, + tcpEstablished = data.tcpEstablished, + openSockets = data.openSockets, + preferIPv4 = data.preferIPv4 + ) + + fun toData(entity: NetworkEntity): JvmMonitoringData.Network = + JvmMonitoringData.Network( + bytesSent = entity.bytesSent, + bytesReceived = entity.bytesReceived, + tcpConnections = entity.tcpConnections, + tcpEstablished = entity.tcpEstablished, + openSockets = entity.openSockets, + preferIPv4 = entity.preferIPv4 + ) + + fun toEntity(data: JvmMonitoringData.ClassLoadingInfo, label: Label): ClassLoadingInfoEntity = + ClassLoadingInfoEntity( + label = label, + loaded = data.loaded, + unloaded = data.unloaded, + codeCacheUsed = data.codeCacheUsed, + codeCacheMax = data.codeCacheMax, + compilationTime = data.compilationTime, + reservedCodeCacheSize = data.reservedCodeCacheSize + ) + + fun toData(entity: ClassLoadingInfoEntity): JvmMonitoringData.ClassLoadingInfo = + JvmMonitoringData.ClassLoadingInfo( + loaded = entity.loaded, + unloaded = entity.unloaded, + codeCacheUsed = entity.codeCacheUsed, + codeCacheMax = entity.codeCacheMax, + compilationTime = entity.compilationTime, + reservedCodeCacheSize = entity.reservedCodeCacheSize + ) + + fun toEntity(data: JvmMonitoringData.Application, label: Label): ApplicationEntity = + ApplicationEntity( + label = label, + httpRequestsCount = data.httpRequestsCount, + httpLatency = data.httpLatency, + dbConnectionsActive = data.dbConnectionsActive, + dbConnectionsMax = data.dbConnectionsMax, + queueTasksPending = data.queueTasksPending, + customMetrics = data.customMetrics.toString() + ) + + fun toData(entity: ApplicationEntity): JvmMonitoringData.Application = + JvmMonitoringData.Application( + httpRequestsCount = entity.httpRequestsCount, + httpLatency = entity.httpLatency, + dbConnectionsActive = entity.dbConnectionsActive, + dbConnectionsMax = entity.dbConnectionsMax, + queueTasksPending = entity.queueTasksPending, + customMetrics = parseCustomMetrics(entity.customMetrics) + ) + + private fun parseCustomMetrics(json: String): Map { + return json + .removePrefix("{").removeSuffix("}") + .split(",") + .mapNotNull { + val parts = it.split("=") + if (parts.size == 2) parts[0].trim() to parts[1].trim() else null + }.toMap() + } +} diff --git a/exporter/src/main/kotlin/lab/monilabexporterex/repository/MetricJpaRepository.kt b/exporter/src/main/kotlin/lab/monilabexporterex/repository/MetricJpaRepository.kt new file mode 100644 index 0000000..146d064 --- /dev/null +++ b/exporter/src/main/kotlin/lab/monilabexporterex/repository/MetricJpaRepository.kt @@ -0,0 +1,26 @@ +package lab.monilabexporterex.repository + +import lab.monilabexporterex.model.* +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository + +@Repository +interface MemoryRepository : JpaRepository + +@Repository +interface GcRepository : JpaRepository + +@Repository +interface ThreadsRepository : JpaRepository + +@Repository +interface CpuRepository : JpaRepository + +@Repository +interface NetworkRepository : JpaRepository + +@Repository +interface ClassLoadingInfoRepository : JpaRepository + +@Repository +interface ApplicationRepository : JpaRepository From 5ca5c32d4a176d380618c14e78c67bc446832c91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=89=E1=85=B5=E1=86=AB=E1=84=92=E1=85=B4=E1=84=89?= =?UTF-8?q?=E1=85=A5=E1=86=BC?= Date: Sat, 18 Oct 2025 15:26:02 +0900 Subject: [PATCH 4/5] =?UTF-8?q?gc=20metric=20get=20service,=20controller?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../monilabexporterex/api/MetricController.kt | 21 ++++++++++++++ .../service/MetricService.kt | 28 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 exporter/src/main/kotlin/lab/monilabexporterex/api/MetricController.kt create mode 100644 exporter/src/main/kotlin/lab/monilabexporterex/service/MetricService.kt diff --git a/exporter/src/main/kotlin/lab/monilabexporterex/api/MetricController.kt b/exporter/src/main/kotlin/lab/monilabexporterex/api/MetricController.kt new file mode 100644 index 0000000..38c47fc --- /dev/null +++ b/exporter/src/main/kotlin/lab/monilabexporterex/api/MetricController.kt @@ -0,0 +1,21 @@ +package lab.monilabexporterex.api + +import lab.monilabexporterex.api.dto.GcMetricResponse +import lab.monilabexporterex.service.MetricService +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/gc") +class MetricController( + private val metricService: MetricService, +) { + + @GetMapping("/metric") + fun getGcMetrics(): ResponseEntity> { + val data = metricService.getAllGcMetrics() + return ResponseEntity.ok(data) + } +} diff --git a/exporter/src/main/kotlin/lab/monilabexporterex/service/MetricService.kt b/exporter/src/main/kotlin/lab/monilabexporterex/service/MetricService.kt new file mode 100644 index 0000000..ed112fc --- /dev/null +++ b/exporter/src/main/kotlin/lab/monilabexporterex/service/MetricService.kt @@ -0,0 +1,28 @@ +package lab.monilabexporterex.service + +import lab.monilabexporterex.api.dto.GcMetricResponse +import lab.monilabexporterex.model.GcEntity +import lab.monilabexporterex.repository.GcRepository +import org.springframework.stereotype.Service + +@Service +class MetricService( + private val gcRepository: GcRepository, +) { + fun getAllGcMetrics(): List { + return gcRepository.findAll().map { it.toResponse() } + } + + private fun GcEntity.toResponse(): GcMetricResponse { + return GcMetricResponse( + id = this.id, + label = this.label.name, + count = this.count, + time = this.time, + pause = this.pause, + allocationRate = this.allocationRate, + liveDataSize = this.liveDataSize, + gcStrategy = this.gcStrategy, + ) + } +} From 37f039d8633568573be9617871c5c02cebf36b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=89=E1=85=B5=E1=86=AB=E1=84=92=E1=85=B4=E1=84=89?= =?UTF-8?q?=E1=85=A5=E1=86=BC?= Date: Sat, 18 Oct 2025 15:33:44 +0900 Subject: [PATCH 5/5] =?UTF-8?q?=EC=8A=A4=ED=82=A4=EB=A7=88=20sql=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exporter/src/main/resources/application.yml | 4 - exporter/src/main/resources/schema.sql | 91 --------------------- 2 files changed, 95 deletions(-) delete mode 100644 exporter/src/main/resources/schema.sql diff --git a/exporter/src/main/resources/application.yml b/exporter/src/main/resources/application.yml index e860c0d..bf2a893 100644 --- a/exporter/src/main/resources/application.yml +++ b/exporter/src/main/resources/application.yml @@ -18,7 +18,3 @@ spring: username: ${DB_USER:root} password: ${DB_PASSWORD:12345} driver-class-name: com.mysql.cj.jdbc.Driver - - sql: - init: - mode: always diff --git a/exporter/src/main/resources/schema.sql b/exporter/src/main/resources/schema.sql deleted file mode 100644 index 81465eb..0000000 --- a/exporter/src/main/resources/schema.sql +++ /dev/null @@ -1,91 +0,0 @@ -CREATE TABLE IF NOT EXISTS tb_metric_memory ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - label VARCHAR(10) NOT NULL, - used BIGINT NOT NULL, - max BIGINT NOT NULL, - committed BIGINT NOT NULL, - eden BIGINT NOT NULL, - survivor BIGINT NOT NULL, - old BIGINT NOT NULL, - buffer_pool_used BIGINT NOT NULL, - max_direct_memory_size BIGINT NOT NULL -); - -CREATE TABLE IF NOT EXISTS tb_metric_gc ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - label VARCHAR(10) NOT NULL, - count BIGINT NOT NULL, - time BIGINT NOT NULL, - pause BIGINT NOT NULL, - allocation_rate DOUBLE NOT NULL, - live_data_size BIGINT NOT NULL, - gc_strategy VARCHAR(255) NOT NULL -); - -CREATE TABLE IF NOT EXISTS tb_metric_threads ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - label VARCHAR(10) NOT NULL, - count INT NOT NULL, - daemon_count INT NOT NULL, - peak_count INT NOT NULL, - deadlocked_count INT NOT NULL, - cpu_time BIGINT NOT NULL, - states TEXT NOT NULL -); - - - -CREATE TABLE IF NOT EXISTS tb_metric_cpu ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - label VARCHAR(10) NOT NULL, - process_usage DOUBLE NOT NULL, - system_usage DOUBLE NOT NULL, - uptime BIGINT NOT NULL, - start_time BIGINT NOT NULL, - load_average DOUBLE NOT NULL, - open_fds BIGINT NOT NULL -); - -CREATE TABLE IF NOT EXISTS tb_metric_network ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - label VARCHAR(10) NOT NULL, - bytes_sent BIGINT NOT NULL, - bytes_received BIGINT NOT NULL, - tcp_connections INT NOT NULL, - tcp_established INT NOT NULL, - open_sockets INT NOT NULL, - prefer_ipv4 BOOLEAN NOT NULL -); - -CREATE TABLE IF NOT EXISTS tb_metric_class_loading ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - label VARCHAR(10) NOT NULL, - loaded INT NOT NULL, - unloaded BIGINT NOT NULL, - code_cache_used BIGINT NOT NULL, - code_cache_max BIGINT NOT NULL, - compilation_time BIGINT NOT NULL, - reserved_code_cache_size BIGINT NOT NULL -); - -CREATE TABLE IF NOT EXISTS tb_metric_class_loading ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - label VARCHAR(10) NOT NULL, - loaded INT NOT NULL, - unloaded BIGINT NOT NULL, - code_cache_used BIGINT NOT NULL, - code_cache_max BIGINT NOT NULL, - compilation_time BIGINT NOT NULL, - reserved_code_cache_size BIGINT NOT NULL -); - -CREATE TABLE IF NOT EXISTS tb_metric_application ( - id BIGINT AUTO_INCREMENT PRIMARY KEY, - label VARCHAR(10) NOT NULL, - http_requests_count BIGINT NOT NULL, - http_latency DOUBLE NOT NULL, - db_connections_active INT NOT NULL, - db_connections_max INT NOT NULL, - queue_tasks_pending INT NOT NULL, - custom_metrics TEXT NOT NULL -);