Skip to content

Commit 6344d27

Browse files
authored
Merge pull request #441 from FlowCI/feature/observability
Feature/observability
2 parents af2b4d6 + a86ecaa commit 6344d27

File tree

9 files changed

+99
-19
lines changed

9 files changed

+99
-19
lines changed

core/debug.yaml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,21 @@ services:
4545
ports:
4646
- "9000:9000"
4747
- "9090:9090"
48-
command: "server /data --console-address \":9090\""
48+
command: "server /data --console-address \":9090\""
49+
50+
prometheus:
51+
image: prom/prometheus:v2.44.0
52+
container_name: prometheus
53+
ports:
54+
- "9191:9090"
55+
volumes:
56+
- ./observability/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
57+
58+
grafana:
59+
image: grafana/grafana:9.5.2
60+
container_name: grafana
61+
ports:
62+
- "3131:3000"
63+
restart: unless-stopped
64+
volumes:
65+
- ./observability/grafana/datasources:/etc/grafana/provisioning/datasources
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: 1
2+
datasources:
3+
- name: Prometheus
4+
type: prometheus
5+
access: proxy
6+
url: http://prometheus:9090
7+
isDefault: true
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
scrape_configs:
2+
- job_name: 'FlowCIMetrics'
3+
metrics_path: '/actuator/prometheus'
4+
scrape_interval: 5s
5+
static_configs:
6+
- targets: ['host.docker.internal:8080']
7+
labels:
8+
application: 'flow.ci'

core/pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@
103103
<artifactId>spring-boot-starter-cache</artifactId>
104104
</dependency>
105105

106+
<dependency>
107+
<groupId>io.micrometer</groupId>
108+
<artifactId>micrometer-registry-prometheus</artifactId>
109+
<scope>runtime</scope>
110+
</dependency>
111+
106112
<dependency>
107113
<groupId>org.eclipse.jgit</groupId>
108114
<artifactId>org.eclipse.jgit</artifactId>
@@ -139,6 +145,12 @@
139145
<configuration>
140146
<mainClass>com.flowci.core.Application</mainClass>
141147
<layout>JAR</layout>
148+
<excludes>
149+
<exclude>
150+
<groupId>org.projectlombok</groupId>
151+
<artifactId>lombok</artifactId>
152+
</exclude>
153+
</excludes>
142154
</configuration>
143155
<executions>
144156
<execution>

core/src/main/java/com/flowci/core/agent/service/AgentServiceImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public void subscribeIdleAgentQueue() throws IOException {
143143
if (shouldPushBack) {
144144
int randomSec = ObjectsHelper.randomNumber(MinIdleAgentPushBack, MaxIdleAgentPushBack);
145145
ThreadHelper.sleep(randomSec * 1000L);
146-
idleAgentQueueManager.send(idleAgentQueue, agentId.getBytes());
146+
idleAgentQueueManager.publish(idleAgentQueue, agentId.getBytes());
147147
}
148148
} catch (Exception e) {
149149
log.warn(e.getMessage());
@@ -307,7 +307,7 @@ public void release(Collection<String> ids) {
307307
update(agent, OFFLINE);
308308
case BUSY:
309309
update(agent, IDLE);
310-
idleAgentQueueManager.send(idleAgentQueue, agentId.getBytes());
310+
idleAgentQueueManager.publish(idleAgentQueue, agentId.getBytes());
311311
}
312312
}
313313
} finally {
@@ -406,7 +406,7 @@ public void onConnected(OnConnectedEvent event) {
406406
update(target, init.getStatus());
407407

408408
if (target.isIdle() && event.isToIdleQueue()) {
409-
idleAgentQueueManager.send(idleAgentQueue, target.getId().getBytes());
409+
idleAgentQueueManager.publish(idleAgentQueue, target.getId().getBytes());
410410
}
411411

412412
event.setAgent(target);

core/src/main/java/com/flowci/core/common/rabbit/RabbitOperations.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import org.springframework.core.task.TaskExecutor;
2626

2727
import java.io.IOException;
28-
import java.util.HashMap;
2928
import java.util.Map;
3029
import java.util.concurrent.ConcurrentHashMap;
3130

@@ -64,19 +63,24 @@ public void declareExchangeAndBind(String exchange,
6463
}
6564

6665
public void declare(String queue, boolean durable) throws IOException {
67-
this.channel.queueDeclare(queue, durable, false, false, null);
66+
this.channel.queueDeclare(queue, durable, false, false, Map.of(
67+
"x-single-active-consumer", true
68+
));
6869
}
6970

7071
public void declareTemp(String queue) throws IOException {
71-
this.channel.queueDeclare(queue, false, false, true, null);
72+
this.channel.queueDeclare(queue, false, false, true, Map.of(
73+
"x-single-active-consumer", true
74+
));
7275
}
7376

7477
public void declare(String queue, boolean durable, Integer maxPriority, String dlExName) throws IOException {
75-
Map<String, Object> props = new HashMap<>(3);
76-
props.put("x-max-priority", maxPriority);
77-
props.put("x-dead-letter-exchange", dlExName);
78-
props.put("x-dead-letter-routing-key", QueueConfig.JobDlRoutingKey);
79-
this.channel.queueDeclare(queue, durable, false, false, props);
78+
this.channel.queueDeclare(queue, durable, false, false, Map.of(
79+
"x-max-priority", maxPriority,
80+
"x-dead-letter-exchange", dlExName,
81+
"x-dead-letter-routing-key", QueueConfig.JobDlRoutingKey,
82+
"x-single-active-consumer", true
83+
));
8084
}
8185

8286
public boolean delete(String queue) {
@@ -108,9 +112,9 @@ public boolean sendToEx(String ex, byte[] body, Map<String, Object> headers) {
108112
}
109113

110114
/**
111-
* Send to routing key with default exchange
115+
* Publish data with routing key to default exchange
112116
*/
113-
public boolean send(String routingKey, byte[] body) {
117+
public boolean publish(String routingKey, byte[] body) {
114118
try {
115119
this.channel.basicPublish(StringHelper.EMPTY, routingKey, null, body);
116120
return true;
@@ -120,9 +124,9 @@ public boolean send(String routingKey, byte[] body) {
120124
}
121125

122126
/**
123-
* Send to routing key with default exchange and priority
127+
* Publish data with routing key and priority to default exchange
124128
*/
125-
public boolean send(String routingKey, byte[] body, Integer priority, int expireInSecond) {
129+
public boolean publish(String routingKey, byte[] body, Integer priority, int expireInSecond) {
126130
try {
127131
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
128132
.priority(priority)

core/src/main/java/com/flowci/core/job/service/JobActionServiceImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ public void accept(JobSmContext context) {
370370
String queue = job.getQueueName();
371371
byte[] payload = job.getId().getBytes();
372372

373-
jobsQueueManager.send(queue, payload, job.getPriority(), job.getExpire());
373+
jobsQueueManager.publish(queue, payload, job.getPriority(), job.getExpire());
374374
logInfo(job, "enqueue");
375375
}
376376

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.flowci.core.metrics;
2+
3+
import com.flowci.core.job.event.JobFinishedEvent;
4+
import io.micrometer.core.instrument.Counter;
5+
import io.micrometer.core.instrument.MeterRegistry;
6+
import lombok.AllArgsConstructor;
7+
import lombok.extern.log4j.Log4j2;
8+
import org.springframework.context.event.EventListener;
9+
import org.springframework.stereotype.Component;
10+
11+
@Component
12+
@Log4j2
13+
@AllArgsConstructor
14+
public class MetricsManager {
15+
16+
private final MeterRegistry meterRegistry;
17+
18+
@EventListener(JobFinishedEvent.class)
19+
public void onJobFinished(JobFinishedEvent e) {
20+
Counter.builder("num_of_finished_job")
21+
.description("num of finished job")
22+
.register(meterRegistry)
23+
.increment();
24+
25+
log.debug("metrics: num_of_finished_job increment");
26+
}
27+
}

core/src/main/resources/application.properties

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
1+
spring.application.name=flow.ci
2+
13
logging.level.org.apache.zookeeper=ERROR
24
logging.level.org.apache.curator.framework=ERROR
35
logging.level.com.flowci.core=${FLOWCI_LOG_LEVEL:INFO}
46

57
info.app.version=1.23.01
6-
info.app.name=flow.ci
8+
info.app.name=${spring.application.name}
79

810
server.port=${FLOWCI_SERVER_PORT:8080}
911
server.address=${FLOWCI_SERVER_ADDRESS:0.0.0.0}
1012
server.tomcat.uri-encoding=UTF-8
1113

14+
management.metrics.tags.application=${spring.application.name}
15+
1216
management.endpoint.health.enabled=true
1317
management.endpoint.health.show-details=always
1418
management.endpoint.shutdown.enabled=true
15-
management.endpoints.web.base-path=/
19+
management.endpoints.web.base-path=/actuator
20+
management.endpoints.web.exposure.include=info,prometheus,metrics,health
1621

1722
spring.servlet.multipart.enabled=true
1823
spring.servlet.multipart.location=${java.io.tmpdir}

0 commit comments

Comments
 (0)