Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ jobs:
run: echo "##[set-output name=version;]$(echo '${{ github.event.head_commit.message }}' | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')"
id: extract_version_name

- name: push
- name: build and push api server
uses: docker/build-push-action@v4
with:
context: .
context: ./deploy/api
platforms: linux/arm64/v8
push: true
tags: |
Expand All @@ -69,6 +69,7 @@ jobs:
"REDIS_HOST=${{ secrets.REDIS_HOST }}"
"REDIS_PORT=${{ secrets.REDIS_PORT }}"
"INTERNAL_SECRET=${{ secrets.INTERNAL_SECRET }}"
"SLACK_TOKEN=${{ secrets.SLACK_TOKEN }}"

deploy:
needs: build
Expand All @@ -79,8 +80,34 @@ jobs:
run: echo "##[set-output name=version;]$(echo '${{ github.event.head_commit.message }}' | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')"
id: extract_version_name

- name: run server
- name: run api server
run: |
sudo docker pull ghcr.io/devxb/gitanimals:${{ steps.extract_version_name.outputs.version }}
sudo docker ps -q --filter "expose=8080" | xargs sudo docker stop | xargs sudo docker rm
sudo docker run -d -p 8081:8080 ghcr.io/devxb/gitanimals:${{ steps.extract_version_name.outputs.version }}
sudo docker run -d -p 8081:8080 -v logs:/logs ghcr.io/devxb/gitanimals:${{ steps.extract_version_name.outputs.version }}

- name: check filebeat status
id: check-status
run: |
if docker ps --filter "name=filebeat" --filter "status=running" --format "{{.Names}}" | grep -q "^filebeat$"; then
echo "Filebeat is already running"
echo "status=running" >> $GITHUB_ENV
else
echo "Filebeat is not running"
echo "status=stopped" >> $GITHUB_ENV
fi

- name: display filebeat status
run: |
if [ "${{ env.status }}" == "running" ]; then
echo "✅ Filebeat is already running"
else
echo "🚀 Filebeat is not running. Starting deployment..."
fi

- name: run file beats
if: env.status == 'running'
run: |
docker build -t filebeat-gitanimals:latest ./deploy/filebeat
docker run -d --name filebeat -v logs:/logs -t filebeat-gitanimals:latest

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ bin/
.DS_Store

.idea
logs
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ sentry {
apply from: "gradle/db.gradle"
apply from: "gradle/core.gradle"
apply from: "gradle/test.gradle"
apply from: "gradle/slack.gradle"
apply from: "gradle/spring.gradle"
apply from: "gradle/monitor.gradle"
apply from: "gradle/logging.gradle"
apply from: "gradle/jetbrains.gradle"
9 changes: 6 additions & 3 deletions Dockerfile → deploy/api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ ARG GITHUB_TOKEN
ARG REDIS_HOST
ARG REDIS_PORT
ARG INTERNAL_SECRET
ARG SLACK_TOKEN

ARG JAR_FILE=./build/libs/*.jar
ARG JAR_FILE=../../build/libs/*.jar
COPY ${JAR_FILE} gitanimals-render.jar

ENV db_url=${DB_URL} \
Expand All @@ -17,7 +18,8 @@ ENV db_url=${DB_URL} \
github_token=${GITHUB_TOKEN} \
redis_host=${REDIS_HOST} \
redis_port=${REDIS_PORT} \
internal_secret=${INTERNAL_SECRET}
internal_secret=${INTERNAL_SECRET} \
slack_token=${SLACK_TOKEN}

ENTRYPOINT java -jar gitanimals-render.jar \
--spring.datasource.url=${db_url} \
Expand All @@ -26,4 +28,5 @@ ENTRYPOINT java -jar gitanimals-render.jar \
--netx.host=${redis_host} \
--netx.port=${redis_port} \
--github.token=${github_token} \
--internal.secret=${internal_secret}
--internal.secret=${internal_secret} \
--slack.token=${slack_token}
16 changes: 16 additions & 0 deletions deploy/filebeat/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Filebeat Base Image
FROM docker.elastic.co/beats/filebeat:8.10.0

# Copy custom Filebeat configuration
COPY filebeat.yml /usr/share/filebeat/filebeat.yml

# Set permissions
USER root
RUN chmod go-w /usr/share/filebeat/filebeat.yml

# Set working directory
WORKDIR /usr/share/filebeat

# Entry point
ENTRYPOINT ["filebeat"]
CMD ["-e", "-c", "/usr/share/filebeat/filebeat.yml"]
18 changes: 18 additions & 0 deletions deploy/filebeat/filebeat.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
filebeat.inputs:
- type: log
enabled: true
paths:
- ./logs/*.json
json:
keys_under_root: true
add_error_key: true

output.elasticsearch:
hosts: ["192.168.0.31:9200"]
username: "elastic"
password: ""

processors:
- decode_json_fields:
fields: ["message"]
target: ""
6 changes: 6 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,9 @@ snowflakeVersion=5.2.5

### Caffeine cache ###
caffeineCacheVersion=3.1.8

### Ecs logback encoder ###
logbackEcsEncoderVersion=1.6.0

### Slack ###
slackVersion=1.40.2
3 changes: 3 additions & 0 deletions gradle/logging.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies {
implementation "co.elastic.logging:logback-ecs-encoder:${logbackEcsEncoderVersion}"
}
5 changes: 5 additions & 0 deletions gradle/slack.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
dependencies {
implementation "com.slack.api:bolt:${slackVersion}"
implementation "com.slack.api:bolt-servlet:${slackVersion}"
implementation "com.slack.api:bolt-jetty:${slackVersion}"
}
44 changes: 44 additions & 0 deletions src/main/kotlin/org/gitanimals/core/appender/SlackAppender.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.gitanimals.core.appender

import ch.qos.logback.classic.Level
import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.core.AppenderBase
import com.slack.api.Slack
import com.slack.api.methods.MethodsClient
import com.slack.api.methods.request.chat.ChatPostMessageRequest

class SlackAppender : AppenderBase<ILoggingEvent>() {

lateinit var slack: MethodsClient

private val errorChannel = "C080GR85WM9"
private val warnChannel = "C08977RL38C"

override fun append(eventObject: ILoggingEvent) {
runCatching {
val channel = when (eventObject.level) {
Level.WARN -> warnChannel
Level.ERROR -> errorChannel
else -> NOT_LOGGING
}

if (channel == NOT_LOGGING) {
return
}

val request: ChatPostMessageRequest = ChatPostMessageRequest.builder()
.channel(channel)
.text(eventObject.formattedMessage)
.build();
slack.chatPostMessage(request)
}
}

fun setToken(token: String) {
this.slack = Slack.getInstance().methods(token)
}

companion object {
private const val NOT_LOGGING = "NOT LOGGING"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.gitanimals.render.controller
import jakarta.servlet.http.HttpServletResponse
import org.gitanimals.render.app.AnimationFacade
import org.gitanimals.core.Mode
import org.slf4j.LoggerFactory
import org.springframework.http.HttpHeaders
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
Expand All @@ -14,6 +15,13 @@ class AnimationController(
private val animationFacade: AnimationFacade,
) {

private val logger = LoggerFactory.getLogger(this::class.simpleName)

@GetMapping("/for-logging-test")
fun forLoggingTest() {
logger.warn("For logging test")
}

@GetMapping(value = ["/farms/{username}"], produces = ["image/svg+xml"])
fun getFarmSvgAnimation(
@PathVariable("username") username: String,
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ netx.orphan-milli=60000
netx.backpressure=40
netx.logging.level=info

slack.token=xoxb-
github.token=a

sentry.dsn=https://fe1aaf784ec135343909a4a0dfe4f0eb@o4505051656486912.ingest.us.sentry.io/4507088960684032
Expand All @@ -31,3 +32,5 @@ internal.secret=a
spring.application.name=render.gitanimals
management.endpoints.web.exposure.include=prometheus
management.metrics.tags.application=${spring.application.name}

logging.level.root=WARN
47 changes: 47 additions & 0 deletions src/main/resources/logback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

<springProperty name="LOG_LEVEL" source="logging.level.root" scope="context"/>
<springProperty name="SERVICE_NAME" source="spring.application.name" scope="context"/>
<springProperty name="slackToken" source="slack.token"/>
<property name="LOG_PATH" value="${LOG_PATH:-./logs}"/>
<property name="LOG_FILE" value="${LOG_FILE:-app}"/>
<property name="LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}][%thread] %-5level %logger{36} - %msg%n"/>
<property name="MAX_HISTORY" value="${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-1}"/>

<appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>

<appender name="ECS_JSON_FILE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder class="co.elastic.logging.logback.EcsEncoder">
<serviceName>${SERVICE_NAME}</serviceName>
</encoder>
<file>${LOG_PATH}/${LOG_FILE}.json</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${LOG_FILE}.json.%d{yyyy-MM-dd}.gz</fileNamePattern>
<maxHistory>${MAX_HISTORY}</maxHistory>
</rollingPolicy>
</appender>
<appender name = "ASYNC_ENC_JSON_FILE_APPENDER" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="ECS_JSON_FILE_APPENDER"/>
</appender>

<appender name="SLACK_APPENDER" class="org.gitanimals.core.appender.SlackAppender">
<param name="token" value="${slackToken}" />
</appender>
<appender name="ASYNC_SLACK_APPENDER" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="SLACK_APPENDER" />
</appender>

<root level="${LOG_LEVEL}">
<appender-ref ref="ASYNC_ENC_JSON_FILE_APPENDER"/>
<appender-ref ref="ASYNC_SLACK_APPENDER"/>
<springProfile name="test">
<appender-ref ref="CONSOLE_APPENDER"/>
</springProfile>
</root>

</configuration>