【AWS経験者向け】CloudWatchとCloud Monitoring:ログとメトリクスの監視設定
はじめに:システムの健全性を監視する「目」
皆さん、こんにちは!「30日間でGCPをマスターするAWSエンジニアの挑戦」シリーズ、22日目へようこそ。
システムの運用において、サービスの健全性を保つためには**監視(モニタリング)**が不可欠です。AWSでは、Amazon CloudWatchがその中心的な役割を担います。メトリクス(CPU使用率、リクエスト数など)の収集、ログの管理、そしてアラーム設定による通知など、システムの「目」として機能します。
GCPにも、これに対応するフルマネージドの監視サービス、Cloud Monitoring(旧Stackdriver)があります。基本的な機能はCloudWatchと似ていますが、GCP独自の統合性や料金体系、設定方法には知っておくべき重要な違いがあります。
この記事では、AWS CloudWatchの知識を前提に、実際の設定ファイルとコード例を交えながら、GCP Cloud Monitoringの運用管理における以下のポイントを詳しく解説します:
- サービス思想と統合性:独立したサービス vs 統合されたプラットフォーム
- 実際の設定方法:具体的な設定ファイルとコマンド例
- メトリクスとログの収集:実装レベルでの比較
- アラート設定:実運用で使える設定例
- コスト最適化:監視コストを抑える実践的なテクニック
サービス思想と統合性:独立 vs 統合
Amazon CloudWatch:独立した「監視サービス」
CloudWatchは、AWSの各サービス(EC2, Lambda, DynamoDBなど)が生成するメトリクスやログを集約して監視する、独立したサービスです。
特徴:
- CloudWatch LogsとCloudWatch Metricsが独立した機能
- 各AWSサービスからデータを収集する「ハブ」的役割
- サービス間の連携には設定が必要
GCP Cloud Monitoring:統合された「運用スイート」の一部
GCP Cloud Monitoringは、Cloud Logging、Cloud Trace、Cloud Profilerと一体となった**「Google Cloud Operations Suite」**の一部として設計されています。
特徴:
- デフォルトで密に連携した統合プラットフォーム
- ログからメトリクスへの変換が標準機能
- より少ない設定でより多くの情報を取得可能
実際の設定方法:CloudWatch vs Cloud Monitoring
CloudWatch エージェントの設定
CloudWatch Agents設定ファイル(amazon-cloudwatch-agent.json):
{
"agent": {
"metrics_collection_interval": 60,
"run_as_user": "cwagent"
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/nginx/access.log",
"log_group_name": "nginx-access-logs",
"log_stream_name": "{instance_id}/nginx-access",
"retention_in_days": 7,
"timestamp_format": "%d/%b/%Y:%H:%M:%S %z"
},
{
"file_path": "/var/log/nginx/error.log",
"log_group_name": "nginx-error-logs",
"log_stream_name": "{instance_id}/nginx-error",
"retention_in_days": 30
}
]
}
}
},
"metrics": {
"namespace": "CWAgent",
"metrics_collected": {
"cpu": {
"measurement": [
"cpu_usage_idle",
"cpu_usage_iowait",
"cpu_usage_user",
"cpu_usage_system"
],
"metrics_collection_interval": 60,
"totalcpu": false
},
"disk": {
"measurement": [
"used_percent"
],
"metrics_collection_interval": 60,
"resources": [
"*"
]
},
"mem": {
"measurement": [
"mem_used_percent"
],
"metrics_collection_interval": 60
}
}
}
}
エージェント起動コマンド:
# エージェントの設定
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config -m ec2 -s \
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
# エージェントの開始
sudo systemctl start amazon-cloudwatch-agent
sudo systemctl enable amazon-cloudwatch-agent
Cloud Monitoring(Ops Agent)の設定
Ops Agent設定ファイル(/etc/google-cloud-ops-agent/config.yaml):
# Google Cloud Ops Agent設定
metrics:
receivers:
# システムメトリクス
hostmetrics:
type: hostmetrics
collection_interval: 60s
# Nginxメトリクス(nginx_statusが有効な場合)
nginx:
type: nginx
stub_status_url: http://localhost:8080/nginx_status
collection_interval: 60s
processors:
# メトリクスのフィルタリング
resourcedetection:
type: resourcedetection
detectors: [gcp, gce]
exporters:
google_cloud_monitoring:
type: google_cloud_monitoring
# プロジェクトIDは自動検出
service:
pipelines:
default_pipeline:
receivers: [hostmetrics, nginx]
processors: [resourcedetection]
exporters: [google_cloud_monitoring]
logging:
receivers:
# システムログ
syslog:
type: files
include_paths:
- /var/log/syslog
- /var/log/messages
# Nginxアクセスログ
nginx_access:
type: files
include_paths:
- /var/log/nginx/access.log
record_log_file_path: true
# 構造化ログの解析
operators:
- type: regex_parser
regex: '^(?P<remote_addr>\S+) - (?P<remote_user>\S+) \[(?P<time_local>[^\]]+)\] "(?P<method>\S+) (?P<path>\S+) (?P<protocol>\S+)" (?P<status>\d+) (?P<body_bytes_sent>\d+) "(?P<http_referer>[^"]*)" "(?P<http_user_agent>[^"]*)"'
timestamp:
parse_from: attributes.time_local
layout: '%d/%b/%Y:%H:%M:%S %z'
# Nginxエラーログ
nginx_error:
type: files
include_paths:
- /var/log/nginx/error.log
record_log_file_path: true
processors:
# ログの加工(任意)
resource:
type: resource
resource_attributes:
service.name: "nginx-server"
service.version: "1.20"
exporters:
google_cloud_logging:
type: google_cloud_logging
service:
pipelines:
default_pipeline:
receivers: [syslog, nginx_access, nginx_error]
processors: [resource]
exporters: [google_cloud_logging]
Ops Agent インストール・設定コマンド:
# Ops Agentのインストール
curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh
sudo bash add-google-cloud-ops-agent-repo.sh --also-install
# 設定ファイルの配置(上記config.yamlを保存後)
sudo cp config.yaml /etc/google-cloud-ops-agent/config.yaml
# エージェントの再起動
sudo systemctl restart google-cloud-ops-agent
# ステータス確認
sudo systemctl status google-cloud-ops-agent
メトリクスとログ:収集方法と管理の詳細比較
| 機能 | AWS CloudWatch | GCP Cloud Monitoring |
|---|---|---|
| 設定の複雑さ | 中程度(JSON設定ファイル) | シンプル(YAML設定) |
| メトリクス自動収集 | 基本メトリクスのみ | より多くの標準メトリクス |
| ログベースメトリクス | Insights + カスタムメトリクス必要 | 標準機能として提供 |
| 構造化ログ解析 | 外部ツール併用が必要 | エージェント内で解析可能 |
| 保持期間 | 設定必要(1日〜永続) | デフォルト30日、400日まで設定可能 |
Cloud Monitoringでのログベースメトリクス作成例
Cloud Loggingでログベースのメトリクスを作成する設定:
# gcloudコマンドでログベースメトリクスを作成
gcloud logging metrics create nginx_4xx_errors \
--description="Nginx 4xx errors count" \
--log-filter='resource.type="gce_instance" AND jsonPayload.status>=400 AND jsonPayload.status<500' \
--value-extractor='EXTRACT(jsonPayload.status)'
# Terraformでの設定例
resource "google_logging_metric" "nginx_error_rate" {
name = "nginx_error_rate"
filter = "resource.type=\"gce_instance\" AND jsonPayload.status>=400"
metric_descriptor {
metric_kind = "GAUGE"
value_type = "INT64"
labels {
key = "status_code"
value_type = "STRING"
description = "HTTP status code"
}
}
label_extractors = {
status_code = "EXTRACT(jsonPayload.status)"
}
}
アラート設定:実運用で使える設定例
CloudWatch Alarms設定例
Terraformでのアラーム設定:
# CPU使用率アラーム
resource "aws_cloudwatch_metric_alarm" "high_cpu" {
alarm_name = "high-cpu-usage"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "2"
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = "300"
statistic = "Average"
threshold = "80"
alarm_description = "This metric monitors ec2 cpu utilization"
alarm_actions = [aws_sns_topic.alerts.arn]
dimensions = {
InstanceId = aws_instance.web.id
}
}
# ログエラー率アラーム
resource "aws_cloudwatch_log_metric_filter" "error_filter" {
name = "ErrorFilter"
log_group_name = aws_cloudwatch_log_group.app.name
pattern = "ERROR"
metric_transformation {
name = "ErrorCount"
namespace = "YourApp"
value = "1"
}
}
resource "aws_cloudwatch_metric_alarm" "error_rate" {
alarm_name = "high-error-rate"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "2"
metric_name = "ErrorCount"
namespace = "YourApp"
period = "300"
statistic = "Sum"
threshold = "10"
treat_missing_data = "notBreaching"
alarm_actions = [aws_sns_topic.alerts.arn]
}
Cloud Monitoring アラートポリシー設定例
Terraformでのアラートポリシー設定:
# CPU使用率アラートポリシー
resource "google_monitoring_alert_policy" "cpu_usage_policy" {
display_name = "High CPU Usage Alert"
combiner = "OR"
conditions {
display_name = "CPU usage above 80%"
condition_threshold {
filter = "resource.type=\"gce_instance\""
duration = "300s"
comparison = "COMPARISON_GREATER_THAN"
threshold_value = 0.8
aggregations {
alignment_period = "300s"
per_series_aligner = "ALIGN_MEAN"
}
}
}
notification_channels = [
google_monitoring_notification_channel.email.name,
google_monitoring_notification_channel.slack.name
]
alert_strategy {
auto_close = "1800s"
}
}
# ログベースメトリクスのアラート
resource "google_monitoring_alert_policy" "error_rate_policy" {
display_name = "High Error Rate Alert"
combiner = "OR"
conditions {
display_name = "Error rate above threshold"
condition_threshold {
filter = "metric.type=\"logging.googleapis.com/user/nginx_4xx_errors\""
duration = "300s"
comparison = "COMPARISON_GREATER_THAN"
threshold_value = 10
aggregations {
alignment_period = "300s"
per_series_aligner = "ALIGN_RATE"
cross_series_reducer = "REDUCE_SUM"
}
}
}
notification_channels = [google_monitoring_notification_channel.email.name]
}
# 通知チャンネル設定
resource "google_monitoring_notification_channel" "email" {
display_name = "Email Notification"
type = "email"
labels = {
email_address = "alerts@yourcompany.com"
}
}
resource "google_monitoring_notification_channel" "slack" {
display_name = "Slack Notification"
type = "slack"
labels = {
channel_name = "#alerts"
url = var.slack_webhook_url
}
}
コスト最適化:監視コストを抑える実践テクニック
CloudWatch コスト最適化
主なコスト要因:
- ログの取り込み量($0.50/GB)
- ログの保存料金($0.03/GB/月)
- カスタムメトリクス($0.30/メトリクス/月)
最適化設定例:
{
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/nginx/access.log",
"log_group_name": "nginx-access-logs",
"retention_in_days": 7,
// ログレベルでフィルタリング
"multi_line_start_pattern": "^\\d{4}-\\d{2}-\\d{2}",
// 不要なログを除外
"exclude_file_path": "/var/log/nginx/access.log*debug*"
}
]
}
}
}
}
Cloud Monitoring コスト最適化
主なコスト要因:
- API呼び出し数(150MB/月まで無料)
- ログの取り込み量(50GB/月まで無料)
最適化設定例:
logging:
receivers:
nginx_access:
type: files
include_paths:
- /var/log/nginx/access.log
operators:
# ヘルスチェックログを除外
- type: filter
expr: 'attributes.path != "/health"'
# 4xx, 5xxエラーのみ保持
- type: filter
expr: 'int(attributes.status) >= 400'
metrics:
receivers:
hostmetrics:
type: hostmetrics
collection_interval: 300s # 間隔を長くしてコスト削減
scrapers:
cpu: {}
memory: {}
# 不要なメトリクスは無効化
# network: {}
# filesystem: {}
実践的な比較表:運用観点から
| 観点 | AWS CloudWatch | GCP Cloud Monitoring |
|---|---|---|
| 初期設定の容易さ | 中程度(JSON設定必要) | 簡単(YAML設定、多くがデフォルト) |
| ログ分析の柔軟性 | CloudWatch Insights(SQL) | Cloud Logging(自然言語クエリ) |
| アラート設定 | SNS連携が必要 | 多様な通知チャネルを標準提供 |
| コスト透明性 | 複雑な料金体系 | シンプルな料金体系 |
| 学習コスト | AWSエンジニアには馴染み深い | 新しい概念の習得が必要 |
| マルチクラウド対応 | AWS専用 | オンプレミス・他クラウドも監視可能 |
まとめ:どちらを選ぶべきか?
AWS CloudWatchとGCP Cloud Monitoringは、どちらも優れた監視サービスですが、その設計思想と運用モデルが大きく異なります。
AWS CloudWatchを選ぶべき場合
- 既存のAWSインフラが大規模
- CloudWatch Logsのクエリ機能に慣れ親しんでいる
- SNSとの統合を活用したい
GCP Cloud Monitoringを選ぶべき場合
- シンプルな設定で包括的な監視を実現したい
- ログとメトリクスを密に連携させたい
- コスト効率を重視したい
- マルチクラウド環境を運用している
特に、GCP環境においてはCloud Monitoringの統合性とシンプルさが大きなアドバンテージとなります。設定ファイルもより直感的で、運用開始までの時間を大幅に短縮できます。
次回は、サーバーレスのメッセージキューサービスであるAWS SQSとGCP Pub/Subを比較し、非同期処理のベストプラクティスを学びましょう。お楽しみに!
この記事が役に立ったという方は、ぜひ「いいね」や「ストック」をお願いします!
シリーズ記事一覧
- [【1日目】はじめの一歩!AWSエンジニアがGCPで最初にやるべきこと]
- [【2日目】GCPのIAMはAWSとどう違う?「プリンシパル」と「ロール」の理解]
- [【3日目】VPCとVPCネットワーク:GCPのネットワーク設計思想を理解する]
- [【4日目】S3とCloud Storage:オブジェクトストレージを徹底比較]
- [【5日目】RDSとCloud SQL:マネージドデータベースの運用管理の違い]
- [【6日目】EC2とCompute Engine:インスタンスの起動から課金モデルまで]
- [【7日目】1週間のまとめ:AWSとGCP、それぞれの得意なことと設計思想]
- [【8日目】EKSとGKE:Kubernetesのマネージドサービスを比較体験!]
- [【9日目】Dockerイメージをどこに置く?ECRとArtifact Registryを比較]
- [【10日目】LambdaとCloud Functions:イベント駆動型サーバーレスの実装]
- [【11日目】API GatewayとCloud Endpoints:API公開のベストプラクティス]
- [【12日目】Cloud Run:サーバーレスでコンテナを動かすGCPの独自サービスを試してみよう]
- [【13日目】AWS FargateとCloud Run:コンテナ運用モデルの根本的な違い]
- [【14日目】2週間のまとめ:GCPのコンテナ・サーバーレス技術はなぜ優れているのか?]
- [【15日目】RedshiftとBigQuery:データウェアハウスのアーキテクチャと料金体系]
- [【16日目】BigQueryをハンズオン!クエリを書いてデータ分析を体験]
- [【17日目】AthenaとBigQuery:データレイクに対するアプローチの違い]
- [【18日目】SageMakerとVertex AI:機械学習プラットフォームの比較]
- [【19日目】BigQuery MLでSQLだけで機械学習モデルを作ってみよう]
- [【20日目】Cloud SQLのレプリカ設定とパフォーマンスチューニング]
- [【21日目】GKE IngressとService Meshの比較]
- [【22日目】CloudWatchとCloud Monitoring:ログとメトリクスの監視設定](この記事)
- [【23日目】SQSとPub/Sub:メッセージキューの比較と実践]