📈

GitHub ActionsでInfluxDBへのデータ登録

2024/10/03に公開

概要

CSVファイルをGitHubにpushした時に、GitHub ActionsでCSVファイルを読み込んでInfluxDBにデータを登録します。

ファイル構成

% tree -aFI .git 
./
├── .github/
│   └── workflows/
│       └── healthcare-data-registration.yml
├── get_last_time.flux
├── healthcare.csv
├── memo.md
└── update.sh

3 directories, 5 files
ファイル名 概要
healthcare-data-registration.yml InfluxDBにデータを登録するGitHub Actionsのワークフロー。
get_last_time.flux InfluxDBから最新のデータを呼び出すためのFluxクエリ。update.shで呼び出す。
healthcare.csv InfluxDBに格納するデータのCSVファイル。
memo.md 思い浮かんだことを書いておくためのメモ。
update.sh healthcare-data-registration.ymlで呼び出す、InfluxDBにデータを書き込むためのシェルスクリプト。

各ファイルの説明

healthcare-data-registration.yml

healthcare-data-registration.yml
healthcare-data-registration.yml
name: Healthcare Data Registration

run-name: Healthcare data registration

on:
  push:
    branches:
      - main
    paths:
      - "healthcare.csv"
  workflow_dispatch:

defaults:
  run:
    shell: bash

jobs:
  Healthcare-Data-Registration:
    runs-on: ubuntu-24.04
    timeout-minutes: 10
    steps:
      - name: Change timezone to Japan
        run: sudo timedatectl set-timezone Asia/Tokyo

      - name: Checkout
        uses: actions/checkout@v4

      - name: Install Influx CLI
        env:
          INFLUX_CLI_URL: https://download.influxdata.com/influxdb/releases/influxdb2-client-2.7.5-linux-amd64.tar.gz
        run: |
          wget ${INFLUX_CLI_URL}
          tar xvzf ./influxdb2-client-2.7.5-linux-amd64.tar.gz
          mv ./influx /usr/local/bin/

      - name: InfluxDB authentication settings
        env:
          INFLUXDB_ORG: Test
          INFLUXDB_TOKEN: ${{ secrets.INFLUXDB_TOKEN }}
          INFLUXDB_URL: https://us-east-1-1.aws.cloud2.influxdata.com
        run: influx config create -a -n healthcare_rw -u ${INFLUXDB_URL} -t "${INFLUXDB_TOKEN}" -o ${INFLUXDB_ORG}

      - name: Healthcare data registration
        run: sh ./update.sh

ワークフローの不要な実行を抑止するために、mainブランチにhealthcare.csvがpushされた時と手動でのみ起動するようにしています。

on:
  push:
    branches:
      - main
    paths:
      - "healthcare.csv"
  workflow_dispatch:

InfluxDBにアクセスするためのAPIトークンはInfluxDBのGUIから取得し、GitHub ActionsのSecretsにINFLUXDB_TOKENとして設定しておいたものを参照します。

      - name: InfluxDB authentication settings
        env:
          INFLUXDB_ORG: Test
          INFLUXDB_TOKEN: ${{ secrets.INFLUXDB_TOKEN }}
          INFLUXDB_URL: https://us-east-1-1.aws.cloud2.influxdata.com
        run: influx config create -a -n healthcare_rw -u ${INFLUXDB_URL} -t "${INFLUXDB_TOKEN}" -o ${INFLUXDB_ORG}

get_last_time.flux

Fluxクエリはsortとlimitで最新のデータだけを取得し、時間だけが欲しいのでkeepで_timeカラムのみを表示します。

get_last_time.flux
get_last_time.flux
from(bucket: "healthcare")
  |> range(start: -30d)
  |> filter(fn: (r) => r._field == "StepCount")
  |> sort(columns: ["_time"], desc: true)
  |> limit(n: 1)
  |> keep(columns: ["_time"])

healthcare.csv

healthcare.csvは以下のようなファイルです。

healthcare.csv
healthcare.csv
Date,UnixTime,StepCount,WalkAndRun,SleepTime,DeepSleepTime,SleepAvarageHeartRate,SleepQuality,MinHeartRate
2024/09/15 0:00,1726326000,8479,1.753129999998491,6:58,0:52,56,69,50
2024/09/16 0:00,1726412400,12407,3.577250000003725,6:55,0:33,53,95,45

memo.md

作っている最中に思い浮かんだメモを書いて、VSCodeのMarkmapで表示しています。
どこかに書いておかないと忘れるので。。。

memo.md
memo.md
# ヘルスケアの可視化
## InfluxDB
### シェルスクリプト
#### 完:登録済みの日付の取得
##### 完:InfluxDBのクエリ(読み込み)
##### 完:登録済みの日付の取得でクエリの結果が空だった時の処理

#### 完:InfluxDBへのデータ格納をcurlからInflux CLIに変更

#### ShellCheck

### GitHub Actions
#### 完:ワークフロー
##### 完:Influx CLIのインストール

#### 完:Secrets設定

#### GitHub ActionsのLinter

#### Secretlint

#### Static Application Security Testing(SATAツール)

#### Conftest

## Grafana

update.sh

influxコマンドでget_last_time.fluxのクエリを使いInfluxDBに格納されたデータの最終時刻を取得し、最終時刻より新しいCSVファイルのエントリをInfluxDBに書き込みます。

update.sh
update.sh
#!/bin/bash

# InfluxDBに格納されたデータの最終日時を取得する。
LAST_TIME=$(influx query @get_last_time.flux | tail -1 | date +%s -f -)

# LAST_TIMEが空の場合、デフォルト値を設定する。
LAST_TIME=${LAST_TIME:-0000000000}

# CSVファイルを読み込み、各行を処理する。
tail -n +2 healthcare.csv | while IFS=',' read -r _ UNIX_TIME STEP_COUNT WALK_AND_RUN SLEEP_TIME DEEP_SLEEP_TIME SLEEP_AVERAGE_HEART_RATE SLEEP_QUALITY MIN_HEART_RATE; do
  # すでに登録済みの日付の場合はスキップする。
  if [ "$UNIX_TIME" -le "$LAST_TIME" ]; then
    continue
  fi

  # 時間を分に変換する関数
  convert_to_minutes() {
    local TIME=$1
    local HOUR=$(echo "$TIME" | awk -F':' '{print $1}')
    local MIN=$(echo "$TIME" | awk -F':' '{print $2}')
    echo $((HOUR * 60 + MIN))
  }

  SLEEP_TIME=$(convert_to_minutes "$SLEEP_TIME")
  DEEP_SLEEP_TIME=$(convert_to_minutes "$DEEP_SLEEP_TIME")

  # InfluxDBにデータを書き込む。
  influx write -b healthcare -p s \
    "HealthCare,device=iPhone StepCount=$STEP_COUNT,WalkAndRun=$WALK_AND_RUN,SleepTime=$SLEEP_TIME,DeepSleepTime=$DEEP_SLEEP_TIME,SleepAverageHeartRate=$SLEEP_AVERAGE_HEART_RATE,SleepQuality=$SLEEP_QUALITY,MinHeartRate=$MIN_HEART_RATE $UNIX_TIME"

  echo "HealthCare,device=iPhone StepCount=$STEP_COUNT,WalkAndRun=$WALK_AND_RUN,SleepTime=$SLEEP_TIME,DeepSleepTime=$DEEP_SLEEP_TIME,SleepAverageHeartRate=$SLEEP_AVERAGE_HEART_RATE,SleepQuality=$SLEEP_QUALITY,MinHeartRate=$MIN_HEART_RATE $UNIX_TIME"

  # 連続して書き込まないために10秒のインターバルを設ける。
  sleep 10
done

参考

https://zenn.dev/tmknom/articles/github-cicd-book

Discussion