logback 環境変数で出力先やログレベルを指定する。

logback.xml に、環境変数の値を適用させるには、
 ${ 環境変数名 } 
の記述方法で指定する。
ログ出力レベル

    <logger name="org.labo">
        <level value="${LOGLEVEL}" />
        <appender-ref ref="FILE" />
    </logger>
環境変数 記述 設定
LOGLEVEL ${LOGLEVEL} "debug" 、"info" などを指定する

ログ出力先、ログパターン

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE logback>
<configuration>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>${LOGDIR}/labo.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${LOGDIR}/labo.%d{yyyy-MM-dd}.log</FileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder>
            <Pattern>%-23d{yyyy/MM/dd HH:mm:ss.SSS} %-5p [%thread] %m\t\t\t[%C{0}.${LOGDETAIL}]%n</Pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    :
  (省略)
環境変数 記述 設定
LOGDIR ${LOGDIR} "/var/log" など出力先パスを指定
LOGDETAIL ${LOGDETAIL} "%method" または、”%method:%line" などを指定

(欠点)
環境変数を必ず指定しなくてはならなくなる。

シェルの2重起動防止

よく見かける方法は、実行するスクリプトでファイルを生成してそのファイル存在チェックで
判定する方法を見かけるが、シェルが途中でハングアップした場合など起動できなくなる。
シェルコマンドのプロセスIDをチェックする正当な方法にすべきだ。

pgrep の結果でチェックする

#!/bin/bash

if [ $$ -ne `pgrep -oxf "/bin/bash $0"` ]; then
    echo "2重起動エラー"
    exit 1
fi

# TODO

`pgrep -oxf "$0"` が正しいかもしれない。。

引数があるなら、

#!/bin/bash

CMDLINE="/bin/bash $0 $@"
if [ $$ -ne  `pgrep -oxf "$CMDLINE"` ]; then
    echo "2重起動エラー"
    exit 1
fi

今更、C-shell なんて書かないだろうけど、C-shell なら、

#!/bin/csh

set CMDLINE=`cat /proc/$$/cmdline xargs --null`
if ($$ != `pgrep -oxf "$CMDLINE"`) then
    echo "2重起動エラー"
    exit 1
endif

Maven ビルドで xml を含める

build で、resource として指定する。

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
    <plugins>
       <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-compiler-plugin</artifactId>
           <version>3.8.0</version>
           <configuration>
              <source>11</source>
              <target>11</target>
           </configuration>
       </plugin>
       
       :
    </plugins>   
       
</build>       

安易な方法かもしれないが。。。

Java 時刻のマイクロ秒精度を表現

JSR-310 java.time.LocalDateTime で、ナノ秒まで表現できる。となったものの
実際OS依存で環境によって、本当に1ナノ秒まで取得できるわけではない。
Windows PCであれば、100ナノ以下は結局、00 であった。
LocalDateTime から java.time.format.DateTimeFormatter 「S」でナノ秒までの文字列

LocalDateTime now = LocalDateTime.now();
String timestring = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS"));

LocalDateTime#getNano() を使う

LocalDateTime now = LocalDateTime.now();
String timestring = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss."))
                  + String.format("%09d", now.getNano());

TimeStamp ミリ秒とナノ秒で現在時刻を生成して

public static Timestamp getNowTimestamp(){
    long millis = System.currentTimeMillis();
    long nanos = System.nanoTime();
    Timestamp timestamp = new Timestamp(millis);
    timestamp.setNanos((int)(nanos % 1000000000));
    return timestamp;
}

TimeStamp → LocalDateTime 変換して、ナノ秒までの文字列

Timestamp timestamp = getNowTimestamp();
String timestring = timestamp.toLocalDateTime()
                    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss."))
                  + String.format("%09d", now.getNano());

マイクロ秒の時刻文字列は、

LocalDateTime now = LocalDateTime.now();
String timestring = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS"));

LocalDateTime#getNano() を使う場合

LocalDateTime now = LocalDateTime.now();
String timestring = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss."))
                  + String.format("%09d", now.getNano()).substring(0, 6);

TimeStamp → LocalDateTime 変換して、ナノ秒までの文字列

Timestamp timestamp = getNowTimestamp();
String timestring = timestamp.toLocalDateTime()
                    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss."))
                  + String.format("%09d", now.getNano()).substring(0, 6);

Maven profile を指定したビルド

profile を指定して、ビルド対象リソースを切り替える

通常のビルド対象リソース
  src/main/resources/application.properties

profile 名=develop として develop のビルド対象リソース
  src/main/resources-develop/application.properties

と用意されている。
pom.xml に profile を記述する。

<profiles>
   <profile>
      <id>develop</id>
      <build>
        <resources>
          <resource>
            <directory>src/main/resources-develop</directory>
          </resource>
          <resource>
            <directory>src/main/resources</directory>
          </resource>
        </resources>
      </build>
    </profile>
</profiles>

これで、src/main/resources にしか存在しないものリソースはそのままビルド対象になり、
src/main/resources-develop で、同じファイル名のリソースが存在すれば、
profile 名=develop を指定したビルドで resources-develop にあるリソースでビルドされる。
以下、-jar で実行するビルドで簡単に試せるであろう。

<build>
   <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.5.2</version>
        <configuration>
          <appendAssemblyId>true</appendAssemblyId>
          <attach>false</attach>
          <finalName>${artifactId}-${project.version}</finalName>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          <appendAssemblyId>false</appendAssemblyId>
          <archive>
            <manifest>
              <mainClass>org.sample.HelloMain</mainClass>
            </manifest>
          </archive>
        </configuration>
        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
   </plugins>
</build>

作成される JARファイル名は、

<finalName>${artifactId}-${project.version}</finalName>

で、一般的なアーティファクトID - バージョン.jar
を指定しているが、違う名前にしたければ、ここを書きかえれば良い。
profile = develop を指定しないビルド

mvn clean package -DskipTests=true

profile = develop を指定するビルド
 -P オプションで、プロファイル名を指定する。

mvn clean package -DskipTests=true -P develop

SpringBoot profile 解説メモ

SpringBoot 環境毎で切り替える方法をまとめた情報のリンクを並べていく、

Spring Boot コア機能 - リファレンスドキュメント


Spring Profilesで環境ごとの設定ファイルを読み込む(SpringBoot2.4の変更も記載) - きり丸の技術日記


Spring Bootでapplication.ymlを環境ごとに分けて利用する方法 - Reasonable Code


Docker runでシステム環境変数または環境別のプロパティファイルを指定する方法