理系学生日記

おまえはいつまで学生気分なのか

Azure Database for MySQLでスロークエリログをLog Analytics Workspaceに連携する

Azure Database for MySQLでも、スロークエリを検出できます。 今回はこのスロークエリログをLog Analytics Workspacesに送信してみます。

Azure Database for MySQLでのスロークエリ取得

Azure Database for MySQLでは、デフォルトだとスロークエリを取得しません。 スロークエリを取得するためには、以下のサーバーパラメータを設定する必要があります。

  • slow_query_log: "ON"に設定することで、スロークエリログ取得が有効化される
  • long_query_time: スロークエリとして検知する閾値。デフォルトは10秒

もう少し細かい設定については、Slow query logs in Azure Database for MySQLを参照してください。

スロークエリログをLog Analytics Workspaceに送信するためには、Azure Database for MySQLに対して診断設定を紐づける必要があります。

Terraformコードは末尾に記載しますが、上記はそのTerraformコードをapplyした結果になります。

動作確認

スロークエリを発生させてみましょう。MySQLではsleepを使えばスロークエリを容易に作成できます。

$ mysql -h kiririmode-mysql.mysql.database.azure.com -u 'kiririmode@kiririmode-mysql.mysql.database.azure.com' -p
mysql> select sleep(11);
+-----------+
| sleep(11) |
+-----------+
|         0 |
+-----------+
1 row in set (11.11 sec)

実際にLog Analytics Workspaces上で、スロークエリTop 3を抽出してみましょう。 KQLは以下になります。

AzureDiagnostics
| where ResourceProvider == "MICROSOFT.DBFORMYSQL" 
| where Category == 'MySqlSlowLogs'
| project TimeGenerated, LogicalServerName_s, event_class_s, start_time_t , query_time_d, sql_text_s 
| top 2 by query_time_d desc

これをLog Analytics Workspaceで実行すると、以下のようにきちんとスロークエリが連携されていることがわかります。

Terraform コード

最初に結論としてのTerraformコードを示すと、おおよそ以下のようなコードになります。

診断設定に対応するazurerm_monitor_diagnostic_settingを用い、CategoryとしてMySqlSlowLogsを指定すれば良いです。

resource "azurerm_mysql_server" "this" {
  name                = var.server_name

  // 略
}

resource "azurerm_monitor_diagnostic_setting" "this" {
  name               = format("%s-diagnostic", var.server_name)
  target_resource_id = azurerm_mysql_server.this.id

  log_analytics_workspace_id = azurerm_log_analytics_workspace.this.id
  dynamic "log" {
    // サーバーパラメータとして"slow_query_log"が"ON"に設定されている場合にのみ
    // log 設定を有効化する
    for_each = try(upper(var.mysql_configurations["slow_query_log"]), "OFF") == "ON" ? [1] : []
    content {
      category = "MySqlSlowLogs"
      enabled  = true

      retention_policy {
        enabled = true
        days    = var.workspace_retentiondays
      }
    }
  }

  dynamic "log" {
    // サーバーパラメータとして"audit_log_enabled"が"ON"に設定されている場合にのみ
    // log 設定を有効化する
    for_each = try(upper(var.mysql_configurations["audit_log_enabled"]), "OFF") == "ON" ? [1] : []
    content {
      category = "MySqlAuditLogs"
      enabled  = true

      retention_policy {
        enabled = true
        days    = var.workspace_retentiondays
      }
    }
  }

  metric {
    category = "AllMetrics"
    enabled  = true

    retention_policy {
      enabled = true
      days    = var.workspace_retentiondays
    }
  }
}

resource "azurerm_log_analytics_workspace" "this" {
  name                = format("%s-workspace", var.server_name)
  resource_group_name = var.resource_group_name
  location            = var.location

  sku                        = var.workspace_sku
  retention_in_days          = var.workspace_retentiondays
  internet_ingestion_enabled = false
  internet_query_enabled     = true
  tags                       = var.tags
}

スロークエリログの有効化はサーバーパラメータslow_query_logで司るため、当該設定がONになっている場合にのみスロークエリの診断設定を有効化しています。