update starter/src: add 2 mod 5 files

This commit is contained in:
jack ning
2025-03-07 18:19:36 +08:00
parent 2446a6c939
commit 13c37269de
4 changed files with 301 additions and 28 deletions

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2025-02-28 17:56:26
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2025-03-07 17:00:40
* @LastEditTime: 2025-03-07 18:08:39
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -13,12 +13,9 @@
*/
package com.bytedesk.ai.springai.dashscope;
import java.util.List;
import java.util.Optional;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.model.Generation;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -32,6 +29,9 @@ import com.bytedesk.core.message.MessageProtobuf;
import com.bytedesk.core.message.MessageTypeEnum;
import lombok.extern.slf4j.Slf4j;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
@Slf4j
@Service
@@ -43,34 +43,61 @@ public class SpringAIDashscopeService extends BaseSpringAIService {
@Qualifier("bytedeskDashScopeChatClient")
private final ChatClient bytedeskDashScopeChatClient;
private final Counter aiRequestCounter;
private final Timer aiResponseTimer;
public SpringAIDashscopeService(
@Qualifier("bytedeskDashScopeChatClient") ChatClient bytedeskDashScopeChatClient,
Optional<SpringAIVectorService> springAIVectorService,
IMessageSendService messageSendService) {
IMessageSendService messageSendService,
MeterRegistry registry) {
super(springAIVectorService, messageSendService);
// this.bytedeskDashScopeChatModel = bytedeskDashScopeChatModel;
this.bytedeskDashScopeChatClient = bytedeskDashScopeChatClient;
// 初始化监控指标
this.aiRequestCounter = Counter.builder("bytedesk.ai.dashscope.requests")
.description("Number of DashScope AI requests")
.register(registry);
this.aiResponseTimer = Timer.builder("bytedesk.ai.dashscope.response.time")
.description("DashScope AI response time")
.register(registry);
}
@Override
protected void processPrompt(Prompt prompt, MessageProtobuf messageProtobuf) {
bytedeskDashScopeChatClient.prompt(prompt.toString())
.stream()
.content()
.subscribe(
content -> {
messageProtobuf.setType(MessageTypeEnum.STREAM);
messageProtobuf.setContent(content);
messageSendService.sendProtobufMessage(messageProtobuf);
},
error -> {
log.error("DashScope API error: ", error);
messageProtobuf.setType(MessageTypeEnum.ERROR);
messageProtobuf.setContent("服务暂时不可用,请稍后重试");
messageSendService.sendProtobufMessage(messageProtobuf);
},
() -> log.info("Chat stream completed")
);
aiRequestCounter.increment();
Timer.Sample sample = Timer.start();
try {
bytedeskDashScopeChatClient.prompt(prompt.toString())
.stream()
.content()
.subscribe(
content -> {
messageProtobuf.setType(MessageTypeEnum.STREAM);
messageProtobuf.setContent(content);
messageSendService.sendProtobufMessage(messageProtobuf);
},
error -> {
log.error("DashScope API error: ", error);
messageProtobuf.setType(MessageTypeEnum.ERROR);
messageProtobuf.setContent("服务暂时不可用,请稍后重试");
messageSendService.sendProtobufMessage(messageProtobuf);
},
() -> {
sample.stop(aiResponseTimer);
log.info("Chat stream completed");
}
);
} catch (Exception e) {
sample.stop(aiResponseTimer);
log.error("Error in processPrompt", e);
messageProtobuf.setType(MessageTypeEnum.ERROR);
messageProtobuf.setContent("服务暂时不可用,请稍后重试");
messageSendService.sendProtobufMessage(messageProtobuf);
}
}

View File

@@ -0,0 +1,220 @@
package com.bytedesk.metrics;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import lombok.extern.slf4j.Slf4j;
/**
* 统一管理监控指标
*/
@Slf4j
@Component
public class BytedeskMetrics {
private final MeterRegistry registry;
// 系统指标
private final Counter totalRequestCounter;
private final Timer httpRequestTimer;
private final Gauge jvmMemoryGauge;
// 用户相关指标
private final Counter onlineUsersCounter;
private final Counter totalUsersCounter;
private final Counter activeUsersCounter;
// 消息相关指标
private final Counter messageCounter;
private final Counter messageErrorCounter;
private final Timer messageProcessTimer;
// AI相关指标
private final Counter aiRequestCounter;
private final Counter aiErrorCounter;
private final Timer aiResponseTimer;
// WebSocket相关指标
private final Counter wsConnectionCounter;
private final Counter wsMessageCounter;
private final Gauge wsActiveConnectionGauge;
@Autowired
public BytedeskMetrics(MeterRegistry registry) {
this.registry = registry;
// 初始化系统指标
this.totalRequestCounter = Counter.builder("bytedesk.requests.total")
.description("Total number of requests")
.register(registry);
this.httpRequestTimer = Timer.builder("bytedesk.http.request.time")
.description("HTTP request processing time")
.register(registry);
this.jvmMemoryGauge = Gauge.builder("bytedesk.jvm.memory",
Runtime.getRuntime(),
runtime -> runtime.totalMemory() - runtime.freeMemory())
.description("JVM memory usage")
.register(registry);
// 初始化用户相关指标
this.onlineUsersCounter = Counter.builder("bytedesk.users.online")
.description("Number of online users")
.register(registry);
this.totalUsersCounter = Counter.builder("bytedesk.users.total")
.description("Total number of registered users")
.register(registry);
this.activeUsersCounter = Counter.builder("bytedesk.users.active")
.description("Number of active users")
.register(registry);
// 初始化消息相关指标
this.messageCounter = Counter.builder("bytedesk.messages.total")
.description("Total number of messages")
.register(registry);
this.messageErrorCounter = Counter.builder("bytedesk.messages.errors")
.description("Number of message errors")
.register(registry);
this.messageProcessTimer = Timer.builder("bytedesk.message.process.time")
.description("Message processing time")
.register(registry);
// 初始化AI相关指标
this.aiRequestCounter = Counter.builder("bytedesk.ai.requests")
.description("Number of AI requests")
.register(registry);
this.aiErrorCounter = Counter.builder("bytedesk.ai.errors")
.description("Number of AI errors")
.register(registry);
this.aiResponseTimer = Timer.builder("bytedesk.ai.response.time")
.description("AI response time")
.register(registry);
// 初始化WebSocket相关指标
this.wsConnectionCounter = Counter.builder("bytedesk.ws.connections")
.description("Number of WebSocket connections")
.register(registry);
this.wsMessageCounter = Counter.builder("bytedesk.ws.messages")
.description("Number of WebSocket messages")
.register(registry);
this.wsActiveConnectionGauge = Gauge.builder("bytedesk.ws.active.connections",
() -> 0D) // 初始值为0
.description("Number of active WebSocket connections")
.register(registry);
}
// 系统指标操作方法
public void incrementRequestCount() {
totalRequestCounter.increment();
}
public Timer.Sample startHttpRequestTimer() {
return Timer.start(registry);
}
public void stopHttpRequestTimer(Timer.Sample sample) {
sample.stop(httpRequestTimer);
}
// 用户相关指标操作方法
public void userConnected() {
onlineUsersCounter.increment();
}
public void userDisconnected() {
onlineUsersCounter.increment(-1);
}
public void newUserRegistered() {
totalUsersCounter.increment();
}
public void userBecameActive() {
activeUsersCounter.increment();
}
public void userBecameInactive() {
activeUsersCounter.increment(-1);
}
// 消息相关指标操作方法
public void messageReceived() {
messageCounter.increment();
}
public void messageError() {
messageErrorCounter.increment();
}
public Timer.Sample startMessageProcessTimer() {
return Timer.start(registry);
}
public void stopMessageProcessTimer(Timer.Sample sample) {
sample.stop(messageProcessTimer);
}
// AI相关指标操作方法
public void aiRequestMade() {
aiRequestCounter.increment();
}
public void aiError() {
aiErrorCounter.increment();
}
public Timer.Sample startAiResponseTimer() {
return Timer.start(registry);
}
public void stopAiResponseTimer(Timer.Sample sample) {
sample.stop(aiResponseTimer);
}
// WebSocket相关指标操作方法
public void wsConnectionOpened() {
wsConnectionCounter.increment();
}
public void wsConnectionClosed() {
wsConnectionCounter.increment(-1);
}
public void wsMessageSent() {
wsMessageCounter.increment();
}
public void updateWsActiveConnections(int count) {
registry.gauge("bytedesk.ws.active.connections", count);
}
// 获取指标值的方法
public double getOnlineUsersCount() {
return onlineUsersCounter.count();
}
public double getTotalMessagesCount() {
return messageCounter.count();
}
public double getAiRequestsCount() {
return aiRequestCounter.count();
}
public double getWsConnectionsCount() {
return wsConnectionCounter.count();
}
}

View File

@@ -0,0 +1,32 @@
package com.bytedesk.starter.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
@Configuration
public class MetricsConfig {
@Bean
public Counter onlineUsersCounter(MeterRegistry registry) {
return Counter.builder("bytedesk.online.users")
.description("Number of online users")
.register(registry);
}
@Bean
public Counter messageCounter(MeterRegistry registry) {
return Counter.builder("bytedesk.messages")
.description("Number of messages processed")
.register(registry);
}
@Bean
public Counter aiRequestCounter(MeterRegistry registry) {
return Counter.builder("bytedesk.ai.requests")
.description("Number of AI requests processed")
.register(registry);
}
}

View File

@@ -154,12 +154,6 @@
<version>${querydsl.version}</version>
</dependency> -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-observation</artifactId>
<scope>provided</scope>
</dependency>
<!-- -->
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
<!-- https://alibaba.github.io/fastjson2/ -->