App Service における Tomcat アプリケーションへの war ファイルのデプロイについて


# App Service 上で稼働する、Tomcat アプリケーションへのデプロイ時に使用する Kudu API がよくわからない！

App Service に war ファイルをデプロイする API として `/api/wardeploy` と `/api/publish` の2種類があり、`/api/wardeploy` のほうがおそらく歴史が古い。
2022年10月現在では、[公式ドキュメント](https://learn.microsoft.com/en-us/azure/app-service/deploy-zip?tabs=api#deploy-warjarear-packages)では`/api/publish`を使うように紹介されており、AZ CLI も内部的には、`/api/publish` を使うようになっている。[^1]
なお、`/api/wardeploy` については、Kudu のリポジトリに [WiKiページ](https://github.com/projectkudu/kudu/wiki/Deploying-WAR-files-using-wardeploy#why-wardeploy) が存在するが、`/api/publish` については存在しない。
どちらを使うべきかわからない、違いがわからないといったことが多いので
本稿では実際に試して見えてきた内容を記載します。

[^1]:`az webapp deploy --debug` で確認可能

# TL;DR

- `/api/publish` を使いましょう
- `/api/publish` を使うとネットワークドライブではなく、インスタンス固有のローカル領域にコピーされる。ファイル I/O のレイテンシの観点や、複数インスタンスの競合を避けるなどのメリットが有る
- ここでいうローカルコピーは Java スタック独自の機能で、App Service の ローカルキャッシュとはべつもの
- ただし `ROOT` コンテキストとなる。
- ローカルコピーを有効にした状態で任意のコンテキストを用いたい場合は、スタートアップスクリプトで対応する必要あり


## 検証環境
OS: Windows
SKU: B1
Java: 11.0.13
Tomcat: 9.0.54[^2]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/b41e3cef-4b25-35eb-7ff9-1c13069fdf55.png)

[^2]:App Service で利用可能なTomcat 9.x 系の最新版(9.0.62)の1世代前

## `/api/wardeploy` と `/api/publish` の違い

ここでの api 実行時には、純粋に Kudu の API の挙動を確認するため、WebApp としては停止状態で行っています。
WebApp が稼働状態の場合、API 実行をトリガーに、アプリケーションの再起動が行われ、初期化処理内でいろいろ行われる(後述)ためです。

### `/api/wardeploy` とは
`/api/wardeploy` については、[WiKi](https://github.com/projectkudu/kudu/wiki/Deploying-WAR-files-using-wardeploy#why-wardeploy) にあるとおり、warファイルの展開をTomcatに実行させずに予め展開した状態で `%HOME%\site\wwwroot\webapps` (Linux の場合は`$HOME/site/wwwroot/webapps`)に配置が行われる。

>  In simplest terms, it takes over the unpacking of the WAR file from Tomcat by unpacking it by itself. The WAR file is unpacked to a temporary location and the unpacked contents are then copied over to the appropriate directory in /home/site/wwwroot/webapps

この動作の目的としては、
`%HOME%` あるいは`$HOME`は、[ネットワークドライブ](https://learn.microsoft.com/ja-jp/azure/app-service/operating-system-functionality#network-drives-unc-shares)ゆえに、複数インスタンスにスケールアウトした状態で、それぞれのインスタンスで動作する Tomcat が war を展開しようとする動作を防ぐことにある。

> However, when you scale out the web app, multiple Tomcat instances race to unpack the WAR file leading to race conditions that may land one or more workers / instances in a bad state. This issue manifests in different ways, most common being a 404 status code when an incoming request is routed to any of the bad workers.

#### 実行例

```bash
curl -X POST -u ${basicauth} "https://${myappName}.scm.azurewebsites.net/api/wardeploy" --data-binary @helloworld.war
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/4609d0e3-89fc-6b74-cdd4-5dcc002f1982.png)

```
dir /b /s
D:\home\site\wwwroot>dir /b /s
D:\home\site\wwwroot\webapps
D:\home\site\wwwroot\webapps\ROOT
D:\home\site\wwwroot\webapps\ROOT\META-INF
D:\home\site\wwwroot\webapps\ROOT\WEB-INF
D:\home\site\wwwroot\webapps\ROOT\index.jsp
D:\home\site\wwwroot\webapps\ROOT\META-INF\maven
省略
```

上記の通り、`ROOT` コンテキストで展開されるため、helloworld.war 内の index.jsp は `https://<appname>.azurewebsites.net/` でアクセスできるようになる。


#### 実行例 name(context) 指定

API実行時に [`name` パラメータを指定することで、指定のコンテキストに展開することもできる](https://github.com/projectkudu/kudu/wiki/Deploying-WAR-files-using-wardeploy#deploying-to-apps-other-than-root)

```bash
curl -X POST -u ${basicauth} "https://${myappName}.scm.azurewebsites.net/api/wardeploy?name=mycontext" --data-binary @helloworld.war
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/5897027f-a655-37f9-f93b-9487e772ab5b.png)

上記の通り、`name`　で指定した コンテキストで展開されるため、helloworld.war 内の index.jsp は `https://<appname>.azurewebsites.net/mycontext/` でアクセスできるようになる。


#### wardeploy 利用時の懸念点

warファイルを事前に展開することで、Tomcat 起動時の複数インスタンスによる競合を避けるメリットはあるものの、あくまでも %HOME% 配下はネットワークドライブとなる。ネットワークドライブである限り、何かしらの接続エラーや、File I/O の遅延の発生の可能性は避けられない。


### `/api/publish` とは

`/api/publish` については、公式ドキュメント上 [Kudu publish API reference](https://learn.microsoft.com/en-us/azure/app-service/deploy-zip?tabs=api#kudu-publish-api-reference) にあるとおり、デフォルトでは、warファイルは、`app.war` として `%HOME%\site\wwwroot`  (Linuxの場合は `$HOME/site/wwwroot`)に配置が行われる。
このとき、`app.war` の展開は行われない。

>　- type=war: Deploy a WAR package. By default, the WAR package is deployed to /home/site/wwwroot/app.war. The target path can be specified with path.


#### 実行例

※事前にwardeployを実行した際のファイルは削除した後に確認しています。

```bash
curl -X POST -u ${basicauth} "https://${myappName}.scm.azurewebsites.net/api/publish?type=war" --data-binary @helloworld.war
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/c1a19cf2-cdbd-0dfb-e9c5-56431b4c782c.png)


#### 実行例 path(context) 指定

path を指定した場合は、そのディレクトリに展開されることになる。（wardeployでnameを指定した場合と同じ挙動）

```bash
curl -X POST -u ${basicauth} "https://${myappName}.scm.azurewebsites.net/api/publish?type=war&path=/home/site/wwwroot/webapps/mycontext" --data-binary @helloworld.war
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/97e87939-a395-2da0-6066-f33268261eb2.png)


```
D:\home\site\wwwroot>dir /b /s
D:\home\site\wwwroot\webapps
D:\home\site\wwwroot\webapps\mycontext
D:\home\site\wwwroot\webapps\mycontext\META-INF
D:\home\site\wwwroot\webapps\mycontext\WEB-INF
D:\home\site\wwwroot\webapps\mycontext\index.jsp
D:\home\site\wwwroot\webapps\mycontext\META-INF\maven
省略
```

## `/api/publish` で配置された `app.war` はどうなるのか？

ここまで `/api/wardeploy` と `/api/publish` そのものの動作の違いを確認してきました。
`/api/publish` を用いると、warファイルは展開されずに `%HOME%\site\wwwroot\app.war` として配置されることがわかりました。

## アプリケーション起動処理

`%HOME%\site\wwwroot` 以下に `app.war` あるいは 展開済みの `webapps/mycontext` ディレクトリが存在する場合に、アプリケーション起動時の動きを見ていきます。

App Service にて Java が言語スタックの場合、Windows 環境では `w3wp.exe` のプロセスの配下に、`JavaBootstrapper`、`cmd`、`java` とプロセスが存在することがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/5f2ed175-bf3d-965f-58e8-3a70977fa6fd.png)

`cmd` はプロセスの Handle からなんとなく `catalina.bat` と考えられますが、その前段の `JavaBootStrapper` は何をしているのかは残念ながら公開情報はありません。

そんなときは、Linux 版を見てみます。なにかヒントがあるかもしれません。

### Linux 版の動作

Linux 環境で Java tomcat スタックのコンテナはどう動いているかを ps で見てみると `java` の他には、`bash /bin/init_container.sh` がいます。名前的に、コンテナのエントリポイントですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/f7b89194-1873-b433-f0d1-2bec0f8a76f7.png)

これを見てみると、ありました。なにやら app.war をコピーするぞって感じの分岐があります。
おそらく、`JavaBootstrapper` も似たようなことをやっているはずです。

```bash:/bin/init_container.sh抜粋
    78  # This is the precedence:
    79  # 1. /home/site/wwwroot/app.war
    80  # 2. /home/site/wwwroot/webapps
    81  # 3. Parking page app
    82  # Note: If /home/site/wwwroot/webapps is used, we copy the app to a local location before using it, unless,
    83  # - Local copy is turned on, in which case /home is pointing to a local share already (so local copy is unnecessary)
    84  # OR
    85  # - WEBSITE_SKIP_LOCAL_COPY is defined to 1 or TRUE.
    86  if [ -f /home/site/wwwroot/app.war ]
    87  then
    88      SITEROOT=/usr/local/tomcat/webapps 
    89      cp /home/site/wwwroot/app.war $SITEROOT/ROOT.war
    90      echo "Using app.war with SITEROOT=$SITEROOT"
    91
    92      # Enable WAR unpacking as we are sure only one app is present at this location
    93      # So we don't have to worry about locking issues. On the other hand, this will provide some performance improvements.
    94      TOMCAT_UNPACK_WARS=true
    95  elif [ ! -d /home/site/wwwroot/webapps ]
    96  then
    97      SITEROOT=/usr/local/appservice/parkingpage
    98      echo "Using parking page app with SITEROOT=$SITEROOT"
    99
   100      # Enable WAR unpacking as we are sure only one app is present at this location
   101      # So we don't have to worry about locking issues. On the other hand, this will provide some performance improvements.
   102      TOMCAT_UNPACK_WARS=true
   103  elif [[ ! -z "$WEBSITE_LOCALCACHE_READY" || "$WEBSITE_SKIP_LOCAL_COPY" = "1"  || "$WEBSITE_SKIP_LOCAL_COPY" = "true" ]]
   104  then
   105      SITEROOT=/home/site/wwwroot/webapps
   106      echo "No local copy needed. SITEROOT=$SITEROOT"
   107  else
   108      SITEROOT=/usr/local/tomcat/webapps
   109      cp -r /home/site/wwwroot/webapps/* $SITEROOT/
   110      echo "Made a local copy of the app and using SITEROOT=$SITEROOT"
   111  fi
```

### catalina.log からの確認

#### %HOME%\site\wwwroot\app.war が配置されている場合(`/api/publish` を使った場合)

`-Dsite.appbase` が `C:/DWASFiles/Sites/アプリ名/Temp/tomcatFiles` で始まるディレクトリが指定されていることがわかります。
すなわち Tomcat は、`%HOME%` はもはや見ていません。
app.war は、ローカル領域(`C:/DWASFiles/Sites/アプリ名/Temp/tomcatFiles`)にすでにコピーされているものと考えられます。

```:catalina.log抜粋
CATALINA_BASE:         D:\Program Files\apache-tomcat-9.0.54
CATALINA_HOME:         D:\Program Files\apache-tomcat-9.0.54
Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
Command line argument: --add-opens=java.base/java.util=ALL-UNNAMED
Command line argument: --add-opens=java.base/java.util.concurrent=ALL-UNNAMED
Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
Command line argument: -Djava.util.logging.config.file=D:\Program Files\apache-tomcat-9.0.54\conf\logging.properties
Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
Command line argument: -Dfile.encoding=UTF-8
Command line argument: -Dcatalina.valves.showReport=False
Command line argument: -Dcatalina.valves.showServerInfo=False
Command line argument: -Dsite.logdir=D:/home/LogFiles
Command line argument: -Dsite.home=C:/DWASFiles/Sites/<アプリ名>/Temp/tomcatFiles/845e1301-9b9c-4834-a578-6db4e85825da
Command line argument: -Dsite.libs=D:/home/site/libs
Command line argument: -Dsite.appbase=C:/DWASFiles/Sites/<アプリ名>/Temp/tomcatFiles/845e1301-9b9c-4834-a578-6db4e85825da/site/wwwroot/webapps
Command line argument: -Dsite.xmlbase=C:/DWASFiles/Sites/<アプリ名>/Temp/tomcatFiles/845e1301-9b9c-4834-a578-6db4e85825da/site/wwwroot
Command line argument: -Dsite.unpackwars=true
Command line argument: -Dsite.tempdir=D:\local\Temp
```

この、インスタンスのローカル領域にファイルをコピーしてくれる機能については、ローカルキャッシュのドキュメントにひっそりと書かれています。（なお、ローカルキャッシュとは別の機能）
https://learn.microsoft.com/en-us/azure/app-service/overview-local-cache

> If you are using Java (Java SE, Tomcat, or JBoss EAP), then by default the Java artifacts--.jar, .war, and .ear files--are copied locally to the worker.

ローカルにコピーするメリットとしては、ネットワークストレージである`%HOME%`(`$HOME`) に比べて、File I/O の向上や、予期せぬネットワークエラーの回避などが考えられます。


#### %HOME%\site\wwwroot\webapps\mycontext 以下に展開済みファイルが配置されている場合(`/api/wardeploy`を利用した場合 、 `/api/publish`でpathを指定した場合)

一方で従来の wardeploy によってすでに war ファイルが　%HOME%\site\wwwroot\webapps 配下に展開されている場合、
`-Dsite.appbase` が、`Dsite.appbase=D:/home/site/wwwroot/webapps` を指しています。
Tomcat は、ネットワークドライブである、%HOME% を見ており、インスタンスのローカル領域にはアプリケーションファイルはコピーされていないという状況です。

```:catalina.log抜粋
CATALINA_BASE:         D:\Program Files\apache-tomcat-9.0.54
CATALINA_HOME:         D:\Program Files\apache-tomcat-9.0.54
Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
Command line argument: --add-opens=java.base/java.util=ALL-UNNAMED
Command line argument: --add-opens=java.base/java.util.concurrent=ALL-UNNAMED
Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
Command line argument: -Djava.util.logging.config.file=D:\Program Files\apache-tomcat-9.0.54\conf\logging.properties
Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
Command line argument: -Dcatalina.valves.showReport=False
Command line argument: -Dcatalina.valves.showServerInfo=False
Command line argument: -Dsite.logdir=D:/home/LogFiles
Command line argument: -Dsite.home=D:/home
Command line argument: -Dsite.libs=D:/home/site/libs
Command line argument: -Dsite.appbase=D:/home/site/wwwroot/webapps
Command line argument: -Dsite.xmlbase=D:/home/site/wwwroot
Command line argument: -Dsite.unpackwars=true
```

### ローカル領域とはなんなのか

残念ながら Kudu UI の DebugConsole からでは、`C:/DWASFiles/Sites/<アプリ名>/Temp/tomcatFiles/` や `%LOCAL_EXPANDED%` の詳細は確認できません。(Linux 版の場合コピー先は `/usr/local/tomcat`となっており、SSH 接続して自由に見ることができます)

そんなときは、スタートアップスクリプト `startup.cmd` (or `startup.ps1`) を利用することでわかります。
スタートアップスクリプトは 以下に説明がある通り、Tomcat が起動する前に（つまり、JavaBootStrapper によって) 実行されます。

https://learn.microsoft.com/en-us/azure/app-service/configure-language-java?pivots=platform-windows#automate-creating-custom-tomcat-on-app-start

> For Windows sites, create a file named startup.cmd or startup.ps1 in the wwwroot directory. This will automatically be executed before the Tomcat server starts.

#### スタートアップスクリプトによる検証

`AZURE_JAVA_APP_PATH` や `AZURE_SITE_HOME` が使えそうです。

https://learn.microsoft.com/en-us/azure/app-service/reference-app-settings?tabs=kudu%2Cjava#language-specific-settings
|Setting name|Description|
|------------|-----------|
|AZURE_JAVA_APP_PATH|Environment variable can be used by custom scripts So they have a location for app.jar after it's copied to loca|
|AZURE_SITE_HOME|The value added to the Java args as -Dsite.home. The default is the value of HOME.|

下記の内容の `startup.cmd` を `%HOME%\site\wwwroot\` に配置してアプリケーションを起動してみます。
```command:%HOME%\site\wwwroot\startup.cmd
set CURRENT_DATE=%date:~10,4%%date:~4,2%%date:~7,2%
set logfile=%HOME%\LogFiles\startup_%CURRENT_DATE%.log

echo "==== startup.cmd start ===" >> "%logfile%" 2>&1
date /t >> "%logfile%" 2>&1
time /t >> "%logfile%" 2>&1

echo "AZURE_JAVA_APP_PATH  = %AZURE_JAVA_APP_PATH%">> "%logfile%" 2>&1
echo "AZURE_SITE_HOME = %AZURE_SITE_HOME%">> "%logfile%" 2>&1

echo "dir %AZURE_SITE_HOME%\site\wwwroot\" >> "%logfile%" 2>&1
dir %AZURE_SITE_HOME%\site\wwwroot >> "%logfile%" 2>&1

echo "dir %AZURE_SITE_HOME%\site\wwwroot\webapps" >> "%logfile%" 2>&1
dir %AZURE_SITE_HOME%\site\wwwroot\webapps >> "%logfile%" 2>&1


echo "==== startup.cmd end ===" >> "%logfile%" 2>&1
```

残念ながら、`%AZURE_JAVA_APP_PATH%`はドキュメントに記載の内容は取得できませんが(追記: JavaSE スタック　Jarデプロイの場合に設定されます。 https://qiita.com/georgeOsdDev@github/items/436b21ffad30f7ca31d8 )、`%AZURE_SITE_HOME%` が catalina.log に出力された `C:/DWASFiles/Sites/<アプリ名>/Temp/tomcatFiles/<ランダム文字列>` に一致します。
そして、
`C:\DWASFiles\Sites\<アプリ名>\Temp\tomcatFiles\211caf6a-7176-48f4-af7f-1b3d3a462d6d\site\wwwroot` 配下に、
`app.war` と `ROOT.xml` と、空の `webapps` ディレクトリが存在していることがわかります。
Tomcat起動前なので、`app.war` はまだ展開されていませんね。

```log:startup.cmdの実行結果
"==== startup.cmd start ===" 
Fri 10/28/2022 
01:41 PM
"AZURE_JAVA_APP_PATH  = "
"AZURE_SITE_HOME = C:\DWASFiles\Sites\<アプリ名>\Temp\tomcatFiles\211caf6a-7176-48f4-af7f-1b3d3a462d6d"
"dir C:\DWASFiles\Sites\<アプリ名>\Temp\tomcatFiles\211caf6a-7176-48f4-af7f-1b3d3a462d6d\site\wwwroot\" 
 Volume in drive C is Temporary Storage
 Volume Serial Number is 484F-9096

 Directory of C:\DWASFiles\Sites\<アプリ名>\Temp\tomcatFiles\211caf6a-7176-48f4-af7f-1b3d3a462d6d\site\wwwroot

10/28/2022  01:41 PM    <DIR>          .
10/28/2022  01:41 PM    <DIR>          ..
10/28/2022  12:58 PM             6,771 app.war
10/28/2022  01:41 PM               156 ROOT.xml
10/28/2022  01:41 PM    <DIR>          webapps
               2 File(s)          6,927 bytes
               3 Dir(s)  11,725,500,416 bytes free
"dir C:\DWASFiles\Sites\<アプリ名>\Temp\tomcatFiles\211caf6a-7176-48f4-af7f-1b3d3a462d6d\site\wwwroot\webapps" 
 Volume in drive C is Temporary Storage
 Volume Serial Number is 484F-9096

 Directory of C:\DWASFiles\Sites\<アプリ名>\Temp\tomcatFiles\211caf6a-7176-48f4-af7f-1b3d3a462d6d\site\wwwroot\webapps

10/28/2022  01:41 PM    <DIR>          .
10/28/2022  01:41 PM    <DIR>          ..
               0 File(s)              0 bytes
               2 Dir(s)  11,725,500,416 bytes free
"==== startup.cmd end ===" 
```

ちなみに ROOT.xml は以下のような内容が記載されていました。
```
<Context displayName="app" docBase="C:\DWASFiles\Sites\<アプリ名>\Temp\tomcatFiles\3c42584b-db11-45cf-acc9-3cf0c0ade9fa\site\wwwroot\app.war" path="" />
```

#### ローカルコピー機能は app.war(= ROOTコンテキスト) 以外は利用できるか

以下のように、startup.cmd の処理内で、app.war を 利用したいコンテキスト.war という名称で `%AZURE_SITE_HOME%\site\wwwroot\webapps\` 配下に移動することでOKでした。
試してないですが、app.war 以外にも、%HOME% のどこかに予め用意しておいた war ファイルを適宜`%AZURE_SITE_HOME%\site\wwwroot\webapps\` 以下にコピーすることで複数コンテキストを動かすことも可能と思われますが、1 WebAppに対しては 1 コンテキストが望ましい。[^3]

[^3]:https://learn.microsoft.com/ja-jp/azure/developer/java/migration/migrate-tomcat-to-tomcat-app-service#create-and-deploy-web-apps


```:startup.cmd
set CURRENT_DATE=%date:~10,4%%date:~4,2%%date:~7,2%
set logfile=%HOME%\LogFiles\startup_%CURRENT_DATE%.log

echo "==== startup.cmd start ===" >> "%logfile%" 2>&1
date /t >> "%logfile%" 2>&1
time /t >> "%logfile%" 2>&1

echo "AZURE_JAVA_APP_PATH  = %AZURE_JAVA_APP_PATH%">> "%logfile%" 2>&1
echo "AZURE_SITE_HOME = %AZURE_SITE_HOME%">> "%logfile%" 2>&1

echo "move %AZURE_SITE_HOME%\site\wwwroot\app.war %AZURE_SITE_HOME%\site\wwwroot\webapps\mycontext.war" >> "%logfile%" 2>&1
move %AZURE_SITE_HOME%\site\wwwroot\app.war %AZURE_SITE_HOME%\site\wwwroot\webapps\mycontext.war >> "%logfile%" 2>&1

echo "delete unused wwwroot\ROOT.xml" >> "%logfile%" 2>&1
del %AZURE_SITE_HOME%\site\wwwroot\ROOT.xml

echo "check %AZURE_SITE_HOME%\site\wwwroot" >> "%logfile%" 2>&1
dir %AZURE_SITE_HOME%\site\wwwroot >> "%logfile%" 2>&1

echo "check %AZURE_SITE_HOME%\site\wwwroot\webapps" >> "%logfile%" 2>&1
dir %AZURE_SITE_HOME%\site\wwwroot\webapps >> "%logfile%" 2>&1

echo "==== startup.cmd end ===" >> "%logfile%" 2>&1
```

```catalina.log抜粋
[main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
[main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/9.0.54]
[main] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [C:\DWASFiles\Sites\<アプリ名>\Temp\tomcatFiles\fdcceda6-132c-48ff-9ae2-090dfbb775c3\site\wwwroot\webapps\mycontext.war]
[main] com.microsoft.azure.appservice.logging.AppServiceLogger.info Log clean up task initializing. Log expiry period = 90 days
[main] com.microsoft.azure.appservice.logging.AppServiceLogger.info Log clean up task initialization succeeded
[main] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [C:\DWASFiles\Sites\<アプリ名>\Temp\tomcatFiles\fdcceda6-132c-48ff-9ae2-090dfbb775c3\site\wwwroot\webapps\mycontext.war] has finished in [6,328] ms
[main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-127.0.0.1-24588"]
[main] org.apache.catalina.startup.Catalina.start Server startup in [8222] milliseconds
```

なお