Skip to content

Instantly share code, notes, and snippets.

@laughk
Created October 27, 2019 02:54
Show Gist options
  • Save laughk/86d02b113e8ea1f19fd3e0ee89fa816d to your computer and use it in GitHub Desktop.
Save laughk/86d02b113e8ea1f19fd3e0ee89fa816d to your computer and use it in GitHub Desktop.
かなり昔に Mackarel で h2o のステータス取得しようとして書いたやつ。公式があるならそっちを使ったほうがいいとは思う
#!/usr/bin/env python3
import os
import datetime
import urllib.request
import json
def fetch_h2o_status(status_url="http://localhost/server-status"):
req = urllib.request.Request(url='{0}/json'.format(status_url))
with urllib.request.urlopen(req) as res:
result = json.loads(res.read().decode('utf-8'))
result.pop('requests')
return result
def show_metadata_for_mackerel():
metadata = {
'graphs': {
'h2o.body-time': {
'label': 'H2O status body time',
'unit': 'integer',
'metric': [
{'name':'0', 'label': None },
{'name':'25', 'label': None },
{'name':'50', 'label': None },
{'name':'75', 'label': None },
{'name':'99', 'label': None },
]
},
'h2o.connect-time': {
'label': 'H2O status connect time',
'unit': 'integer',
'metric': [
{'name':'0', 'label': None },
{'name':'25', 'label': None },
{'name':'50', 'label': None },
{'name':'75', 'label': None },
{'name':'99', 'label': None },
]
},
'h2o.connections': {
'label': 'H2O status connections',
'unit': 'integer',
'metric': [
{'name':'current', 'label': 'current connections'},
{'name':'max', 'label': 'max connections'}
]
},
'h2o.duration': {
'label': 'H2O status duration',
'unit': 'integer',
'metric': [
{'name':'0', 'label': None },
{'name':'25', 'label': None },
{'name':'50', 'label': None },
{'name':'75', 'label': None },
{'name':'99', 'label': None },
]
},
'h2o.body-time': {
'label': 'H2O status body time',
'unit': 'integer',
'metric': [
{'name':'0', 'label': None },
{'name':'25', 'label': None },
{'name':'50', 'label': None },
{'name':'75', 'label': None },
{'name':'99', 'label': None },
]
},
'h2o.http2': {
'label': 'H2O status http2',
'unit': 'integer',
'metric': [
{'name':'read-closed', 'label': None},
{'name':'write-closed', 'label': None}
]
},
'h2o.http2-errors': {
'label': 'H2O status http2 error',
'unit': 'integer',
'metric': [
{'name': 'cancel', 'label': None},
{'name': 'compression', 'label': None},
{'name': 'connect', 'label': None},
{'name': 'enhance-your-calm', 'label': None},
{'name': 'flow-control', 'label': None},
{'name': 'frame-size', 'label': None},
{'name': 'inadequate-security', 'label': None},
{'name': 'internal', 'label': None},
{'name': 'protocol', 'label': None},
{'name': 'refused-stream', 'label': None},
{'name': 'settings-timeout', 'label': None},
{'name': 'stream-closed', 'label': None},
]
},
'h2o.listeners': {
'label': 'H2O status listeners',
'unit': 'integer',
'metric': [
{'name': 'listeners', 'label': None}
]
},
'h2o.num-sessions': {
'label': 'H2O status num-sessions',
'unit': 'integer',
'metric': [
{'name': 'num-sessions', 'label': None}
]
},
'h2o.process-time': {
'label': 'H2O status process-time',
'unit': 'integer',
'metric': [
{'name':'0', 'label': None },
{'name':'25', 'label': None },
{'name':'50', 'label': None },
{'name':'75', 'label': None },
{'name':'99', 'label': None },
]
},
'h2o.request-total-time': {
'label': 'H2O status request-total-time',
'unit': 'integer',
'metric': [
{'name':'0', 'label': None },
{'name':'25', 'label': None },
{'name':'50', 'label': None },
{'name':'75', 'label': None },
{'name':'99', 'label': None },
]
},
'h2o.response-time': {
'label': 'H2O status response-time',
'unit': 'integer',
'metric': [
{'name':'0', 'label': None },
{'name':'25', 'label': None },
{'name':'50', 'label': None },
{'name':'75', 'label': None },
{'name':'99', 'label': None },
]
},
'h2o.status-errors': {
'label': 'H2O status status-error',
'unit': 'integer',
'metric': [
{'name': '400', 'label': None},
{'name': '403', 'label': None},
{'name': '404', 'label': None},
{'name': '405', 'label': None},
{'name': '416', 'label': None},
{'name': '417', 'label': None},
{'name': '500', 'label': None},
{'name': '502', 'label': None},
{'name': '503', 'label': None},
]
},
'h2o.uptime': {
'label': 'H2O status uptime',
'unit': 'integer',
'metric': [
{'name': 'current', 'label': None}
]
},
'h2o.worker-threads': {
'label': 'H2O status worker-threads',
'unit': 'integer',
'metric': [
{'name': 'worker-threads', 'label': None}
]
},
}
}
print(json.dumps(metadata, indent=2))
def migrate_h2o_status(h2o_status):
result = []
key_prefix = 'h2o'
for i in ['openssl-version', 'restart-time', 'server-version', 'generation']:
h2o_status.pop(i)
current_time = datetime.datetime.strptime(h2o_status.pop('current-time'), '%d/%b/%Y:%H:%M:%S %z')
current_time_unix = int(current_time.timestamp())
for key, value in h2o_status.items():
if 'body-time' in key:
key = key.replace('body-time-', 'body-time.')
elif 'connect-time' in key:
key = key.replace('connect-time-', 'connect-time.')
elif 'duration' in key:
key = key.replace('duration-', 'duration.')
elif 'header-time' in key:
key = key.replace('header-time-', 'header-time.')
elif 'timss-time' in key:
key = key.replace('process-time-', 'process-time.')
elif 'request-total-time' in key:
key = key.replace('request-total-time-', 'request-total-time.')
elif 'response-time' in key:
key = key.replace('response-time-', 'response-time.')
elif 'connection' in key:
if key == 'connections':
key = '{0}.current'.format(key)
elif key == 'max-connections':
key = 'connections.max'
elif 'uptime' in key:
key = 'uptime.current'
result.append(('{0}.{1}'.format(key_prefix, key), str(value), str(current_time_unix)))
return result
def output_tsv(h2o_status):
for i in h2o_status:
print('\t'.join(i))
def main():
if os.environ.get('MACKEREL_AGENT_PLUGIN_META'):
show_metadata_for_mackerel()
else:
raw_h2o_status = fetch_h2o_status()
h2o_status = migrate_h2o_status(raw_h2o_status)
output_tsv(h2o_status)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment