1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
| @Configuration public class MetricsConfiguration { @Bean public TimedAspect timedAspect(MeterRegistry registry) { return new TimedAspect(registry); } @Bean public CountedAspect countedAspect(MeterRegistry registry) { return new CountedAspect(registry); } @Bean public Counter userCreationCounter(MeterRegistry registry) { return Counter.builder("user.creation.total") .description("用户创建总数") .register(registry); } @Bean public Timer userCreationTimer(MeterRegistry registry) { return Timer.builder("user.creation.duration") .description("用户创建耗时") .register(registry); } @Bean public Gauge activeUsersGauge(MeterRegistry registry, UserService userService) { return Gauge.builder("user.active.count") .description("活跃用户数量") .register(registry, userService, UserService::getActiveUserCount); } }
@Service public class MetricUserService { private final UserRepository userRepository; private final Counter userCreationCounter; private final Timer userCreationTimer; private final MeterRegistry meterRegistry; public MetricUserService(UserRepository userRepository, Counter userCreationCounter, Timer userCreationTimer, MeterRegistry meterRegistry) { this.userRepository = userRepository; this.userCreationCounter = userCreationCounter; this.userCreationTimer = userCreationTimer; this.meterRegistry = meterRegistry; } @Timed(name = "user.creation", description = "用户创建耗时") @Counted(name = "user.creation.attempts", description = "用户创建尝试次数") public User createUser(CreateUserRequest request) { return Timer.Sample.start(meterRegistry) .stop(userCreationTimer.wrap(() -> { try { User user = new User(request.getUsername(), request.getEmail(), request.getPassword()); User savedUser = userRepository.save(user); userCreationCounter.increment( Tags.of( Tag.of("result", "success"), Tag.of("source", "api") ) ); return savedUser; } catch (Exception e) { userCreationCounter.increment( Tags.of( Tag.of("result", "failure"), Tag.of("error", e.getClass().getSimpleName()) ) ); throw e; } })); } public long getActiveUserCount() { return userRepository.countByLastLoginAfter( LocalDateTime.now().minusDays(7) ); } public void recordUserLogin(Long userId, String source) { meterRegistry.counter("user.login.total", Tags.of( Tag.of("source", source), Tag.of("user.type", getUserType(userId)) ) ).increment(); } public void recordApiCall(String endpoint, String method, int statusCode, long duration) { Timer.builder("api.request.duration") .tag("endpoint", endpoint) .tag("method", method) .tag("status", String.valueOf(statusCode)) .register(meterRegistry) .record(duration, TimeUnit.MILLISECONDS); } private String getUserType(Long userId) { return userId < 1000 ? "premium" : "regular"; } }
@RestController @RequestMapping("/metrics") public class CustomMetricsController { private final MeterRegistry meterRegistry; private final UserService userService; public CustomMetricsController(MeterRegistry meterRegistry, UserService userService) { this.meterRegistry = meterRegistry; this.userService = userService; } @GetMapping("/business") public ResponseEntity<Map<String, Object>> getBusinessMetrics() { Map<String, Object> metrics = new HashMap<>(); metrics.put("totalUsers", getTotalUsers()); metrics.put("activeUsers", getActiveUsers()); metrics.put("newUsersToday", getNewUsersToday()); metrics.put("memoryUsage", getMemoryUsage()); metrics.put("cpuUsage", getCpuUsage()); metrics.put("apiCallsPerMinute", getApiCallsPerMinute()); metrics.put("errorRate", getErrorRate()); return ResponseEntity.ok(metrics); } private long getTotalUsers() { return meterRegistry.get("user.creation.total").counter().count(); } private long getActiveUsers() { return (long) meterRegistry.get("user.active.count").gauge().value(); } private long getNewUsersToday() { return userService.countUsersCreatedAfter(LocalDate.now().atStartOfDay()); } private double getMemoryUsage() { return meterRegistry.get("jvm.memory.used").gauge().value(); } private double getCpuUsage() { return meterRegistry.get("system.cpu.usage").gauge().value(); } private double getApiCallsPerMinute() { return meterRegistry.get("api.request.duration").timer().count() / 60.0; } private double getErrorRate() { Timer timer = meterRegistry.get("api.request.duration").timer(); long totalRequests = (long) timer.count(); long errorRequests = meterRegistry.get("api.request.duration") .tag("status", "500") .timer() .count(); return totalRequests > 0 ? (double) errorRequests / totalRequests : 0.0; } }
|