この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
こんにちは。
くコ:彡がトレードマークの阿部です。
CloudWatch Logsを使うと、OSやアプリケーションログをAWSに転送する事が出来ます。
Linux、Windowsを問わずに利用可能です。
CloudWatch LogsでAmazonLinux上のApacheエラーログを監視する
AWS CloudWatch LogsでWindows OSのイベントログを収集する
ログファイルを介さずに文字列をPUTする事は出来ないのだろうか?と疑問に思いました。
というわけで、AWS CLIのput-log-events
コマンドを使って、文字列をPUTしてみました。
ロググループの作成
AWSマネージメントコンソールからCloudWatchにアクセスし、左メニュー[ログ]を選択します。
アクション -> ロググループの作成で、ロググループを作成します。
ここでは、Testというロググループを作成しました。
ログストリームの作成
作成したロググループを選択し、ログストリームの作成を選択します。
ここでは、App1いうログストリームを作成しました。
ログイベントのPUT
put-log-events
コマンドを使って、メッセージ「Hello CloudWatch」をPUTしてみます。
ロググループとログストリームは先ほど作成したものを指定します。タイムスタンプは、long型で記載します。
OutputにnextSequenceToken
が表示されます。
$ aws logs put-log-events --log-group-name "Test" --log-stream-name "App1" --log-events timestamp=1461997171845,message='Hello CloudWatch'
{
"nextSequenceToken": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX436652582946"
}
$
ログストリームを確認すると、ログイベントが追加されている事がわかります。
今度は別のメッセージをPUTしてみます。
トークンが無効であるメッセージが表示され、失敗してしまいました。
ログイベントをPUTする場合、リクエストに1つ前のリクエストで表示されたトークン(nextSequenceToken
)を含める必要があります。
$ aws logs put-log-events --log-group-name "Test" --log-stream-name "App1" --log-events timestamp=1461997617646,message='Message 2'
A client error (InvalidSequenceTokenException) occurred when calling the PutLogEvents operation: The given sequenceToken is invalid. The next expected sequenceToken is:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX436652582946
$
初回のPUT時に表示されたトークンを指定して、PUTしてみます。
今度はPUT出来ました。
$ aws logs put-log-events --log-group-name "Test" --log-stream-name "App1" --log-events timestamp=1461997617646,message='Message 2' --sequence-token XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX436652582946
{
"nextSequenceToken": "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY350958389282"
}
$
トークンの表示
2回目以降のPUTでは、put-log-events
で表示されるトークンの指定が必要でした。
連続してPUTする場合は良いですが、1つ前のトークンを控えておくのは大変です。
describe-log-streams
コマンドを使えば、次のPUTに必要なトークンを表示する事が可能です。
uploadSequenceToken
に注目すると、前回のPUT時に表示されたnextSequenceToken
と同じ値である事がわかります。
$ aws logs describe-log-streams --log-group-name "Test"
{
"logStreams": [
{
"firstEventTimestamp": 1461997171845,
"lastEventTimestamp": 1461997617646,
"creationTime": 1461996716218,
"uploadSequenceToken": "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY350958389282",
"logStreamName": "App1",
"lastIngestionTime": 1461998112607,
"arn": "arn:aws:logs:ap-northeast-1:aws-accountid:log-group:Test:log-stream:App1",
"storedBytes": 0
}
]
}
$
スクリプト
任意の文字列をPUTするスクリプトを作ってみました。
使い方
コードをput-log-events.sh
として、保存して下さい。引数にPUTしたいメッセージを指定し、実行します。
$ ./put-log-events.sh "messages 3"
{
"nextSequenceToken": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ667119339554"
}
$
実行結果
コード
UploadSequenceToken
コマンドを実行しトークンを取得出来なかった場合、トークンを指定せずにPUTします。
トークンを取得できた場合、そのトークンを指定してPUTします。
#!/bin/bash
# リージョン
export AWS_DEFAULT_REGION=ap-northeast-1
# CloudWatchLogs設定
LogGroupName="Test"
LogStreamName="App1"
# CloudWatchLogsにPUTするメッセージ
Mess=$1
# コーテーションを取り除く
Mess=`echo $Mess | sed -e "s/'//g"`
# put-log-eventに利用するトークン
UploadSequenceToken=$(aws logs describe-log-streams --log-group-name "$LogGroupName" --query 'logStreams[?logStreamName==`'$LogStreamName'`].[uploadSequenceToken]' --output text)
# put-log-eventに利用するタイムスタンプ
TimeStamp=`date "+%s%N" --utc`
TimeStamp=`expr $TimeStamp / 1000000`
# put-log-eventsの実行
if [ "$UploadSequenceToken" != "None" ]
then
# トークン有りの場合
aws logs put-log-events --log-group-name "$LogGroupName" --log-stream-name "$LogStreamName" --log-events timestamp=$TimeStamp,message="$Mess" --sequence-token $UploadSequenceToken
else
# トークン無しの場合(初回のput)
aws logs put-log-events --log-group-name "$LogGroupName" --log-stream-name "$LogStreamName" --log-events timestamp=$TimeStamp,message="$Mess"
fi
おわりに
CloudWatch Logsに文字列をPUTしてみました。
上手く使えば、ローカルにログを持たずにすみそうですね。
では、またお会いしましょう。