Skip to content

Commit

Permalink
feat(UserActivityManager) : DAU, MAU계산 및 export
Browse files Browse the repository at this point in the history
- 로그인시 계정 없음에 대한 에러코드를 정의하였습니다.
- 로그인시 하루 기준으로 중복되지 않는 사용자에 대해 카운트하고, metricRegistry를 통해 export 합니다.
  • Loading branch information
Due-IT committed Dec 10, 2024
1 parent dd1a89e commit 7e89339
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 2 deletions.
2 changes: 2 additions & 0 deletions wabi/src/main/kotlin/com/wap/wabi/WabiApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import jakarta.annotation.PostConstruct
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.data.jpa.repository.config.EnableJpaAuditing
import org.springframework.scheduling.annotation.EnableScheduling
import java.util.TimeZone

@SpringBootApplication
@EnableJpaAuditing
@EnableScheduling
class WabiApplication {
@PostConstruct
fun started() {
Expand Down
13 changes: 13 additions & 0 deletions wabi/src/main/kotlin/com/wap/wabi/auth/admin/entity/Admin.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,17 @@ public Admin build() {
return new Admin(this);
}
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Admin admin = (Admin) o;
return id.equals(admin.id);
}

@Override
public int hashCode() {
return id.hashCode();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.wap.wabi.auth.admin.payload.response.AdminLoginResponse
import com.wap.wabi.auth.admin.repository.AdminRefreshTokenRepository
import com.wap.wabi.auth.admin.repository.AdminRepository
import com.wap.wabi.auth.admin.util.AdminValidator
import com.wap.wabi.auth.admin.util.UserActivityManager
import com.wap.wabi.auth.jwt.JwtTokenProvider
import com.wap.wabi.exception.ErrorCode
import com.wap.wabi.exception.RestApiException
Expand All @@ -20,7 +21,8 @@ class AdminService(
private val adminRefreshTokenRepository: AdminRefreshTokenRepository,
private val tokenProvider: JwtTokenProvider,
private val adminValidator: AdminValidator,
private val encoder: PasswordEncoder
private val encoder: PasswordEncoder,
private val userActivityManager: UserActivityManager
) {
@Transactional
fun registerAdmin(adminRegisterRequest: AdminRegisterRequest) {
Expand All @@ -36,7 +38,11 @@ class AdminService(
adminValidator.validateLogin(adminLoginRequest)
val admin = adminRepository.findByName(adminLoginRequest.name)
?.takeIf { admin ->
encoder.matches(adminLoginRequest.password, admin.get().password)
try {
encoder.matches(adminLoginRequest.password, admin.get().password)
} catch (e: Exception) {
throw RestApiException(ErrorCode.BAD_REQUEST_ADMIN_LOGIN)
}
}
?: throw RestApiException(ErrorCode.BAD_REQUEST_NOT_EXIST_ADMIN)
val refreshToken = tokenProvider.createRefreshToken()
Expand All @@ -54,6 +60,7 @@ class AdminService(
)

val accessToken = tokenProvider.createAccessToken("${admin.get().username}:${admin.get().role}")
userActivityManager.updateUserActivity(admin.get())
return AdminLoginResponse(
name = admin.get().username,
role = admin.get().role,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.wap.wabi.auth.admin.util

import com.wap.wabi.auth.admin.entity.Admin
import io.micrometer.core.instrument.Gauge
import io.micrometer.core.instrument.Metrics
import org.slf4j.LoggerFactory
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Component


@Component
class UserActivityManager {
private var dauCounter = 0
private var mauCounter = 0

private val activeUsersToday = HashSet<Admin>()

private val logger = LoggerFactory.getLogger(UserActivityManager::class.java)

fun updateUserActivity(admin: Admin) {
if (activeUsersToday.add(admin)) {
dauCounter++
mauCounter++
}

Gauge.builder("user_activity_dau") { dauCounter }.register(Metrics.globalRegistry)
Gauge.builder("user_activity_mau") { mauCounter }.register(Metrics.globalRegistry)
}

@Scheduled(cron = "0 0 0 * * ?")
fun resetDailyActiveUser() {
dauCounter = 0
activeUsersToday.clear()
logger.info("Reset daily active user")
}

@Scheduled(cron = "0 0 0 1 * ?")
fun resetMonthlyActiveUser() {
mauCounter = 0
logger.info("Reset monthly active user")
}
}
1 change: 1 addition & 0 deletions wabi/src/main/kotlin/com/wap/wabi/exception/ErrorCode.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ enum class ErrorCode(
BAD_REQUEST_ADMIN_NAME(HttpStatus.BAD_REQUEST, "800-3", "이름이 형식에 맞지 않습니다."),
BAD_REQUEST_EXIST_ADMIN(HttpStatus.BAD_REQUEST, "800-4", "이미 존재하는 어드민입니다."),
BAD_REQUEST_NOT_EXIST_ADMIN(HttpStatus.BAD_REQUEST, "800-5", "존재하지 않는 어드민입니다."),
BAD_REQUEST_ADMIN_LOGIN(HttpStatus.BAD_REQUEST, "800-6", "일치하는 계정이 없습니다."),
}

0 comments on commit 7e89339

Please sign in to comment.