Slide 1

Slide 1 text

無い機能ならつくってしまえ、カスタムメトリック JDDUG#10 Japan Datadog User Group 2025/5/28 ファニーギーク 鹿野 市郎

Slide 2

Slide 2 text

ボランティアと副業の話

Slide 3

Slide 3 text

自己紹介 Profile ◼ 所属/経歴 • 電機メーカー勤務 • 経歴 1. サーバーのグローバル製造技術/営業 2. データセンター・プロジェクト 3. マネージドサービス(マルチクラウド・ハイブリッドクラウド) ◼ 個人活動 • 副業:FunnyGeek ITサービス(ファニーギーク) • ボランティア:CoderDojo青梅(主宰/Champion) • IBM チャンピオン:IBM Champion 2018-2025, 8year Milestone • Datadog アンバサダー:Datadog Ambassador 2024-2025 • 特定非営利活動法人 青梅こども未来 プログラミング講師 • 特定非営利活動法人 青梅の虹any, Rainbow Room プログラミング講師 • 特定非営利活動法人 多摩川流域生活支援ネットワーク, ポラリスキッズ プログラミング講師 • 一般社団法人 情報通信ネットワーク産業協会 CIAJ 調査統計員会 2024委員長 • 一般財団法人 科学技術継承財団 理事 KANO Ichiro 鹿野 市郎

Slide 4

Slide 4 text

ボランティア(CoderDojo青梅) 毎月3回、無料のプログラミング倶楽部を開催(小3~高校) 入門・初級 上級 ラズパイ・ Python, JS オンライン

Slide 5

Slide 5 text

ボランティア(CoderDojo青梅) 入門・初級Scratchプログラミング ・簡単に見えるけど(実際に簡単) ・大人にも難しいプログラムを作れる

Slide 6

Slide 6 text

ボランティア(CoderDojo青梅) 上級プログラミング ・ラズパイロボットに実装したカメラ映像 ・ノートPCで遠隔のロボットをリモート運転 ・Linux ・Python ・JavaScript ・Node-RED

Slide 7

Slide 7 text

副業(マンツーマン・プログラミング) 個別支援プログラミング講師  特定非営利活動法人 青梅こども未来  特定非営利活動法人 青梅の虹any, レインボールーム  特定非営利活動法人 多摩川流域生活支援ネットワーク, ポラリスキッズ • 初級プログラミング Scratch • 上級プログラミング JavaScript, MySQL • キントーン導入&伴走サポート • PC導入&修理 • WEBサイト制作

Slide 8

Slide 8 text

きっかけ(会社での話)

Slide 9

Slide 9 text

きっかけ(会社での話) バックエンド・アプリの応答が遅いことがある。 もしかしてTCPポート16011の接続数が超過している? TCPポート16011の接続数を モニタリングしてみましょうか。 ? ?

Slide 10

Slide 10 text

きっかけ(会社での話) 応答時間 tcp.response_time 接続可否 tcp.can_connect 接続総数 net.tcp.current_established 接続総数 net.tcp.connections あれ? 特定TCPポートの接続数が見つからない... Hi イチロー TCPポート毎の接続数はモニタリングできないけれど、よさげな要望なので 将来リクエストに投稿しとくね。 代案は netstat か ss コマンドでTCPポート数をカウントするのはどう?

Slide 11

Slide 11 text

Linuxコマンド $ ss –ant4 | grep ':22' | grep ESTAB | wc –l 2 [ss]コマンドでTCPポートの状態を取得できる LISTEN 0 128 0.0.0.0:22 0.0.0.0:* ESTAB 0 1154 133.18.***.***:22 115.151.***.***:45448 ESTAB 0 52 133.18.***.***:22 220.146.***.***:50794 値を取得できれば、Datadogのメトリックを作成できる! Datadog エージェント カスタム Check ダッシュボード

Slide 12

Slide 12 text

やり方(Datadogエージェントでのカスタムメトリック) Step1 Step2 検査するための python コード チェックを作る[例:/checks.d/kano.py] 設定を記述 コンフィグを作る[例:/conf.d/kano.yaml]

Slide 13

Slide 13 text

やり方(Datadogエージェントでのカスタムメトリック) https://docs.datadoghq.com/ja/developers/custom_checks/write_agent_check/ 参考: 公式サイトに「ロードバランサ」のサンプルが紹介されています

Slide 14

Slide 14 text

やり方(Datadogエージェントでのカスタムメトリック) Step1 コンフィグを書く init_config: instances: - min_collection_interval: 15 ← メトリック収集間隔 port: 22 ← TCPポート番号 /etc/datadog-agent/conf.d/kano.yaml

Slide 15

Slide 15 text

やり方(Datadogエージェントでのカスタムメトリック) Step2 チェックを作る from datadog_checks.base import AgentCheck class KanoCheck(AgentCheck): def check(self, instance): try: tcp_port = instance.get(‘port‘); // コンフィグの値を読む command = "ss -ant4 | grep ':" + tcp_port + "' | grep ESTAB | wc -l"; result = subprocess.run( command, shell=True, 略 ) # 結果をメトリックスとしてDatadogインテークサーバーへ送信 self.gauge( 'custom_tcp.connections', ← 好きなメトリック名を定義 int( result.stdout.strip() ), ← メトリックの値 [例: suctome_tcp.connections = 2] tags=['host:kano_server'] ← 好きな属性を追加 ) 注:あちこち省略してます /etc/datadog-agent/checks.d/kano.py

Slide 16

Slide 16 text

エージェントで検査(カスタムメトリック) $ sudo systemctl restart datadog-agent $ sudo datadog-agent check kano

Slide 17

Slide 17 text

エージェントで検査(カスタムメトリック) Datadog エージェント カスタム Check ダッシュボード ↑ 次、ここを検査

Slide 18

Slide 18 text

ダッシュボードで検査(カスタムメトリック) ▼モニタリング対象サーバー ダッシュボードに取り込んだメトリック▼

Slide 19

Slide 19 text

ダッシュボード・ウィジェット作成 TCPポート番号別の 接続数が可視化できた! [いつ、何個、ポート番号]

Slide 20

Slide 20 text

ボランティア・副業での話

Slide 21

Slide 21 text

運用しているサーバー5台(ボランティア, 副業) JitsiMeet Minecraft apache1 apache2 apache3 mySQL Node-RED nginx WordPress1 WordPress2 WordPress3 node.js mySQL WEBサイト WEBアプリ開発 ジッチミート, DBサーバー マイクラ サンドボックス(トライアル)

Slide 22

Slide 22 text

ジッチミート・サーバー

Slide 23

Slide 23 text

ジッチミート・サーバー Jitsi Meet ①オンラインイベント開催 ②NPO法人オンライン会議 いつ、何人参加しているのか。安定して稼働しているか。 特長:全員が画面共有できる!一人ずつの進捗が見える

Slide 24

Slide 24 text

ジッチミート・サーバー JitsiMeetには 統計 を取得するAPIがある { "endpoints_with_suspended_sources":0, "inactive_endpoints":2, "inactive_conferences":1, "total_ice_succeeded_relayed":0, "bit_rate_download":1, "local_active_endpoints":0, "muc_clients_connected":1, "total_participants":2, "total_packets_received":0, "rtt_aggregate":0.0, "packet_rate_upload":0, "p2p_conferences":1, "preemptive_kfr_suppressed":0, "local_endpoints":2, "octo_send_bitrate":0, "total_dominant_speaker_changes":0, "endpoints_with_spurious_remb":0, "receive_only_endpoints":0, "octo_receive_bitrate":0, "total_colibri_web_socket_messages_received":0, "total_visitors":0, "version":"2.3.220-g7cda0a66", "total_colibri_web_socket_messages_sent":0, "total_bytes_sent_octo":0, "total_ice_succeeded":2, "total_data_channel_messages_received":7, "total_conference_seconds":0, "visitors":0, "num_eps_oversending":0, "bit_rate_upload":0, "total_conferences_completed":0, "octo_conferences":0, "num_eps_no_msg_transport_after_delay":0, "endpoints_sending_video":0, "packet_rate_download":5, "muc_clients_configured":1, "outgoing_loss":0.0, "overall_loss":0.0, "total_packets_sent_octo":0, "total_layering_changes_received":0, "total_relays":0, "endpoints_with_high_outgoing_loss":0, "stress_level":0.12951601908657123, "drain":false, "total_video_stream_milliseconds_received":0, "shutting_down":false, "octo_endpoints":0, "current_timestamp":"2025-04-21 13:33:36.656", "num_relays_no_msg_transport_after_delay":0, "conferences":1, "participants":2, "total_keyframes_received":0, "average_participant_stress":0.01, "largest_conference":2, "total_packets_sent":0, "endpoints":2, "total_data_channel_messages_sent":10, ・・・ $ curl http://localhost:8080/colibri/stats

Slide 25

Slide 25 text

ジッチミート・サーバー カスタムメトリックを取得する checks.d と conf.d from datadog_checks.base import AgentCheck import requests __version__ = "0.0.1" class KanoJitsimeetCheck(AgentCheck): def check(self, instance): url = instance.get('url') if not url: self.log.error("No URL provided in instance configuration") raise ValueError("The 'url' field is required in the instance configuration") try: response = requests.get(url) if response.status_code == 200: data = response.json() self.gauge('custom_jitsimeet.total_participants', data.get('participants', 0)) self.gauge('custom_jitsimeet.total_conferences', data.get('conferences', 0)) else: self.service_check('custom_jitsimeet.api_check', self.CRITICAL) except Exception as e: self.log.error(f"Error while fetching data from {url}: {e}") self.service_check('custom_jitsimeet.api_check', self.CRITICAL) /etc/datadog-agent/conf.d/jitsimeet.yaml init_config: instances: - name: jitsimeet_stats_check url: http://localhost:8080/colibri/stats timeout: 5 headers: Accept: application/json tags: - environment:jitsimeet - api:colibri-stats collect_response_time: true method: GET include_content: true /etc/datadog-agent/conf.d/http_check.yaml

Slide 26

Slide 26 text

ジッチミート・サーバー [会議数]と[参加者数]を可視化できた 4人 会議 1個 2人 落ちた

Slide 27

Slide 27 text

ジッチミート・サーバー

Slide 28

Slide 28 text

Minecraft・サーバー

Slide 29

Slide 29 text

Minecraft・サーバー オンラインゲーム: 正常性いつでも遊べる状態か。どんな頻度で何人くらい遊んでいるか。

Slide 30

Slide 30 text

Minecraft・サーバー TCPポート 25565 の接続数をカウントして参加者数を可視化できた

Slide 31

Slide 31 text

Minecraft・サーバー 土曜日のお昼~夕方の様子 2人 3人

Slide 32

Slide 32 text

監視アラートの話

Slide 33

Slide 33 text

監視アラート こんなことないですか? 例えば朝イチに、メールをチェックしたら監視アラートが届いている ダッシュボードを見に行ったら、全部OK アラート誤検出、もしくは復旧済み。Recoveryメールあるが…。

Slide 34

Slide 34 text

監視アラート 私たちが見たいのはこれでは? ひと目で何時頃、どれくらい、 どのサーバーに障害が起きていたのか、影響範囲も分かる。

Slide 35

Slide 35 text

監視アラート 私たちが見たいのはこれでは? Hi イチロー 今のところ、そのような機能はありません。 だけど、よさげな要望なので将来リクエストに投稿しとくね。

Slide 36

Slide 36 text

監視アラート ところで Synthetics の Tests には在る この部分をダッシュボードに置きたい!

Slide 37

Slide 37 text

監視アラート Synthetics 監視は[Test ID]がある

Slide 38

Slide 38 text

監視アラート [Test ID]のステータスをカウントして時系列に可視化。それっぽい。

Slide 39

Slide 39 text

まとめ

Slide 40

Slide 40 text

まとめ ⚫ オンライン会議(ジッチミート)は、会議数と参加者数を可視化できた ✓ カスタムメトリック(統計API取得) ⚫ ゲーム(マイクラ)は、利用者数を可視化できた ✓ カスタムメトリック(TCPポート毎の接続数) ⚫ 監視アラートは、時系列BARで可視化できた(■■■■■■) ✓ グラフ(Synthetic @Test IDでStatusカウント)

Slide 41

Slide 41 text

無い機能ならつくってしまえ、カスタムメトリック