├── .idea ├── .name ├── dictionaries │ └── jieli.xml ├── encodings.xml ├── vcs.xml ├── misc.xml ├── modules.xml ├── dataSources.local.xml ├── CrazyMonitor.iml └── dataSources.xml ├── monitor ├── __init__.py ├── migrations │ ├── __init__.py │ └── 0002_auto_20170407_1608.py ├── backends │ ├── __init__.py │ ├── dump.rdb │ ├── host_status.py │ ├── redis_conn.py │ ├── perpetual_machine.py │ └── management.py ├── templatetags │ ├── __init__.py │ └── custom_tags.py ├── apps.py ├── tests.py ├── api_urls.py ├── urls.py ├── auth.py ├── admin.py ├── views.py └── graphs.py ├── CrazyMonitor ├── __init__.py ├── wsgi.py ├── urls.py └── settings.py ├── statics ├── unity │ └── img │ │ ├── flags │ │ ├── united-kingdom.png.tmp │ │ ├── italy.png │ │ ├── spain.png │ │ ├── france.png │ │ ├── germany.png │ │ └── united-kingdom.png │ │ ├── av1.png │ │ ├── av2.png │ │ ├── av4.png │ │ ├── error.jpg │ │ ├── login.jpg │ │ ├── logo.png │ │ ├── balloon.jpg │ │ ├── expanded.jpg │ │ ├── login-bg.jpg │ │ ├── slidein.jpg │ │ ├── collapsed.jpg │ │ ├── offcanvas.jpg │ │ └── revealing.jpg ├── plugins │ └── highstock │ │ ├── js │ │ ├── adapters │ │ │ ├── standalone-framework.js │ │ │ └── standalone-framework.src.js │ │ ├── modules │ │ │ ├── no-data-to-display.js │ │ │ ├── funnel.js │ │ │ ├── solid-gauge.js │ │ │ ├── offline-exporting.js │ │ │ ├── no-data-to-display.src.js │ │ │ └── boost.js │ │ └── themes │ │ │ ├── grid-light.js │ │ │ ├── skies.js │ │ │ ├── sand-signika.js │ │ │ ├── grid.js │ │ │ ├── dark-unica.js │ │ │ ├── dark-green.js │ │ │ ├── dark-blue.js │ │ │ └── gray.js │ │ ├── graphics │ │ ├── snow.png │ │ ├── sun.png │ │ ├── search.png │ │ ├── skies.jpg │ │ ├── highslide │ │ │ ├── close.png │ │ │ ├── closeX.png │ │ │ ├── resize.gif │ │ │ ├── zoomout.cur │ │ │ └── outlines │ │ │ │ └── rounded-white.png │ │ └── meteogram-symbols-30px.png │ │ ├── examples │ │ ├── .DS_Store │ │ ├── basic-line │ │ │ └── index.htm │ │ ├── spline │ │ │ └── index.htm │ │ ├── step-line │ │ │ └── index.htm │ │ ├── navigator-disabled │ │ │ └── index.htm │ │ ├── scrollbar-disabled │ │ │ └── index.htm │ │ ├── markers-only │ │ │ └── index.htm │ │ ├── line-markers │ │ │ └── index.htm │ │ ├── arearange │ │ │ └── index.htm │ │ ├── columnrange │ │ │ └── index.htm │ │ ├── areasplinerange │ │ │ └── index.htm │ │ ├── ohlc │ │ │ └── index.htm │ │ ├── column │ │ │ └── index.htm │ │ ├── candlestick │ │ │ └── index.htm │ │ ├── styled-scrollbar │ │ │ └── index.htm │ │ ├── intraday-candlestick │ │ │ └── index.htm │ │ ├── area │ │ │ └── index.htm │ │ ├── areaspline │ │ │ └── index.htm │ │ ├── yaxis-reversed │ │ │ └── index.htm │ │ ├── flags-placement │ │ │ └── index.htm │ │ ├── intraday-area │ │ │ └── index.htm │ │ ├── dynamic-update │ │ │ └── index.htm │ │ ├── compare │ │ │ └── index.htm │ │ ├── yaxis-plotbands │ │ │ └── index.htm │ │ ├── intraday-breaks │ │ │ └── index.htm │ │ ├── flags-general │ │ │ └── index.htm │ │ ├── yaxis-plotlines │ │ │ └── index.htm │ │ ├── data-grouping │ │ │ └── index.htm │ │ ├── candlestick-and-volume │ │ │ └── index.htm │ │ ├── flags-shapes │ │ │ └── index.htm │ │ └── lazy-loading │ │ │ └── index.htm │ │ ├── gfx │ │ └── vml-radial-gradient.png │ │ ├── readme.txt │ │ └── index.htm ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── fontawesome-webfont.woff2 │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── css │ ├── custom.css │ └── dashboard.css └── js │ ├── npm.js │ ├── holder.min.js │ ├── ie10-viewport-bug-workaround.js │ ├── custom.js │ └── ie-emulation-modes-warning.js ├── CrazyMonitorClient ├── __init__.py ├── bin │ ├── __init__.py │ └── CrazyClient.py ├── conf │ ├── __init__.py │ └── settings.py ├── core │ ├── __init__.py │ ├── main.py │ └── client.py └── plugins │ ├── __init__.py │ ├── linux │ ├── __init__.py │ ├── MegaCli │ ├── host_alive.py │ ├── network.py │ ├── cpu_mac.py │ ├── mac_load.py │ └── memory.py │ ├── windows │ ├── __init__.py │ └── sysinfo.py │ └── plugin_api.py ├── monitor_db.sqlite3 ├── share └── screeshots │ ├── flow.png │ ├── monitor1.png │ └── monitor2.png ├── templates ├── dashboard.html ├── monitor │ ├── triggers.html │ ├── dashboard.html │ ├── trigger_list.html │ ├── base.html │ └── host_groups.html ├── hosts.html └── base.html ├── manage.py ├── MonitorServer.py ├── README.md └── .gitignore /.idea/.name: -------------------------------------------------------------------------------- 1 | CrazyMonitor -------------------------------------------------------------------------------- /monitor/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CrazyMonitor/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /monitor/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /statics/unity/img/flags/united-kingdom.png.tmp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/adapters/standalone-framework.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/adapters/standalone-framework.src.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /CrazyMonitorClient/__init__.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | -------------------------------------------------------------------------------- /monitor/backends/__init__.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | -------------------------------------------------------------------------------- /monitor/templatetags/__init__.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | -------------------------------------------------------------------------------- /CrazyMonitorClient/bin/__init__.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | -------------------------------------------------------------------------------- /CrazyMonitorClient/conf/__init__.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | -------------------------------------------------------------------------------- /CrazyMonitorClient/core/__init__.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | -------------------------------------------------------------------------------- /CrazyMonitorClient/plugins/__init__.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'jieli' 3 | -------------------------------------------------------------------------------- /monitor_db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/monitor_db.sqlite3 -------------------------------------------------------------------------------- /CrazyMonitorClient/plugins/linux/__init__.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | -------------------------------------------------------------------------------- /CrazyMonitorClient/plugins/windows/__init__.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | -------------------------------------------------------------------------------- /monitor/backends/dump.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/monitor/backends/dump.rdb -------------------------------------------------------------------------------- /share/screeshots/flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/share/screeshots/flow.png -------------------------------------------------------------------------------- /statics/unity/img/av1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/av1.png -------------------------------------------------------------------------------- /statics/unity/img/av2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/av2.png -------------------------------------------------------------------------------- /statics/unity/img/av4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/av4.png -------------------------------------------------------------------------------- /statics/unity/img/error.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/error.jpg -------------------------------------------------------------------------------- /statics/unity/img/login.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/login.jpg -------------------------------------------------------------------------------- /statics/unity/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/logo.png -------------------------------------------------------------------------------- /share/screeshots/monitor1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/share/screeshots/monitor1.png -------------------------------------------------------------------------------- /share/screeshots/monitor2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/share/screeshots/monitor2.png -------------------------------------------------------------------------------- /statics/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /statics/unity/img/balloon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/balloon.jpg -------------------------------------------------------------------------------- /statics/unity/img/expanded.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/expanded.jpg -------------------------------------------------------------------------------- /statics/unity/img/login-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/login-bg.jpg -------------------------------------------------------------------------------- /statics/unity/img/slidein.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/slidein.jpg -------------------------------------------------------------------------------- /.idea/dictionaries/jieli.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /statics/unity/img/collapsed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/collapsed.jpg -------------------------------------------------------------------------------- /statics/unity/img/flags/italy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/flags/italy.png -------------------------------------------------------------------------------- /statics/unity/img/flags/spain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/flags/spain.png -------------------------------------------------------------------------------- /statics/unity/img/offcanvas.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/offcanvas.jpg -------------------------------------------------------------------------------- /statics/unity/img/revealing.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/revealing.jpg -------------------------------------------------------------------------------- /monitor/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class MonitorConfig(AppConfig): 5 | name = 'monitor' 6 | -------------------------------------------------------------------------------- /statics/unity/img/flags/france.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/flags/france.png -------------------------------------------------------------------------------- /statics/unity/img/flags/germany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/flags/germany.png -------------------------------------------------------------------------------- /statics/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /statics/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /statics/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /templates/dashboard.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block right-panel-content %} 4 | dfdfdfsddddddddddd 5 | {% endblock %} -------------------------------------------------------------------------------- /CrazyMonitorClient/plugins/linux/MegaCli: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/CrazyMonitorClient/plugins/linux/MegaCli -------------------------------------------------------------------------------- /monitor/backends/host_status.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | 4 | 5 | 6 | def update_host_status(): 7 | pass -------------------------------------------------------------------------------- /statics/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /templates/monitor/triggers.html: -------------------------------------------------------------------------------- 1 | {% extends 'monitor/index.html' %} 2 | 3 | {% block page-title %} 4 | 5 | 触发器 6 | {% endblock %} -------------------------------------------------------------------------------- /statics/plugins/highstock/graphics/snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/plugins/highstock/graphics/snow.png -------------------------------------------------------------------------------- /statics/plugins/highstock/graphics/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/plugins/highstock/graphics/sun.png -------------------------------------------------------------------------------- /statics/unity/img/flags/united-kingdom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/unity/img/flags/united-kingdom.png -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/plugins/highstock/examples/.DS_Store -------------------------------------------------------------------------------- /statics/plugins/highstock/graphics/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/plugins/highstock/graphics/search.png -------------------------------------------------------------------------------- /statics/plugins/highstock/graphics/skies.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/plugins/highstock/graphics/skies.jpg -------------------------------------------------------------------------------- /templates/monitor/dashboard.html: -------------------------------------------------------------------------------- 1 | {% extends 'monitor/index.html' %} 2 | 3 | {% block page-title %} 4 | 5 | 监控大盘 6 | {% endblock %} 7 | 8 | -------------------------------------------------------------------------------- /statics/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /statics/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /statics/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /statics/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /statics/plugins/highstock/gfx/vml-radial-gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/plugins/highstock/gfx/vml-radial-gradient.png -------------------------------------------------------------------------------- /statics/plugins/highstock/graphics/highslide/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/plugins/highstock/graphics/highslide/close.png -------------------------------------------------------------------------------- /statics/plugins/highstock/graphics/highslide/closeX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/plugins/highstock/graphics/highslide/closeX.png -------------------------------------------------------------------------------- /statics/plugins/highstock/graphics/highslide/resize.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/plugins/highstock/graphics/highslide/resize.gif -------------------------------------------------------------------------------- /statics/plugins/highstock/graphics/highslide/zoomout.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/plugins/highstock/graphics/highslide/zoomout.cur -------------------------------------------------------------------------------- /statics/plugins/highstock/graphics/meteogram-symbols-30px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/plugins/highstock/graphics/meteogram-symbols-30px.png -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /statics/plugins/highstock/graphics/highslide/outlines/rounded-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devops/CrazyMonitor/master/statics/plugins/highstock/graphics/highslide/outlines/rounded-white.png -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /statics/plugins/highstock/readme.txt: -------------------------------------------------------------------------------- 1 | 产品名称: Highstock 2 | 3 | 版本: 4.2.4 4 | 5 | 发布时间: 2016-04-15 6 | 7 | 使用方法:直接打开 index.htm 即可看到我们提供的离线例子清单;所有需要的 js 文件在 /js/ 目录里。 8 | 9 | power by Highcharts中文网(http://wwww.hcharts.cn/) 10 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /statics/css/custom.css: -------------------------------------------------------------------------------- 1 | 2 | .graph-container { 3 | 4 | margin-top: 25px; 5 | } 6 | 7 | .severity-5{ 8 | background-color: red; 9 | } 10 | .severity-4{ 11 | background-color: orangered; 12 | } 13 | .severity-3{ 14 | background-color: yellow; 15 | } -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CrazyMonitor.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MonitorServer.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | import os 4 | import sys 5 | 6 | if __name__ == "__main__": 7 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CrazyMonitor.settings") 8 | 9 | from monitor.backends.management import execute_from_command_line 10 | 11 | execute_from_command_line(sys.argv) 12 | -------------------------------------------------------------------------------- /monitor/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | 5 | 6 | # if cpu.idle < 10 or cpu.iowait > 30 and mem.usage > 90 = warning 7 | # 8 | # 9 | # 10:10:00 10:11:00 10 | # 10:09:10 10:10:10 11 | 12 | 13 | from django.db import models 14 | 15 | class Host(models.Model): 16 | pass 17 | 18 | class -------------------------------------------------------------------------------- /CrazyMonitorClient/bin/CrazyClient.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | 4 | import sys 5 | import os 6 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 7 | sys.path.append(BASE_DIR) 8 | 9 | from core import main 10 | 11 | if __name__ == "__main__": 12 | client = main.command_handler(sys.argv) 13 | 14 | 15 | -------------------------------------------------------------------------------- /monitor/backends/redis_conn.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | 4 | import redis 5 | 6 | def redis_conn(django_settings): 7 | #print(django_settings.REDIS_CONN) 8 | pool = redis.ConnectionPool(host=django_settings.REDIS_CONN['HOST'], port=django_settings.REDIS_CONN['PORT']) 9 | r = redis.Redis(connection_pool=pool) 10 | return r -------------------------------------------------------------------------------- /CrazyMonitor/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for CrazyMonitor project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CrazyMonitor.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /CrazyMonitorClient/conf/settings.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | 4 | 5 | configs ={ 6 | 'HostID': 1, 7 | "Server": "localhost", 8 | "ServerPort": 9000, 9 | "urls":{ 10 | 11 | 'get_configs' :['api/client/config','get'], #acquire all the services will be monitored 12 | 'service_report': ['api/client/service/report/','post'], 13 | 14 | }, 15 | 'RequestTimeout':30, 16 | 'ConfigUpdateInterval': 300, #5 mins as default 17 | 18 | } -------------------------------------------------------------------------------- /monitor/api_urls.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | from django.conf.urls import url 4 | 5 | from monitor import views 6 | 7 | urlpatterns = [ 8 | 9 | url(r'client/config/(\d+)/$',views.client_configs ), 10 | url(r'client/service/report/$',views.service_data_report ), 11 | url(r'hosts/status/$',views.hosts_status,name='get_hosts_status' ), 12 | url(r'groups/status/$',views.hostgroups_status,name='get_hostgroups_status' ), 13 | url(r'graphs/$',views.graphs_generator,name='get_graphs' ) 14 | 15 | ] 16 | -------------------------------------------------------------------------------- /CrazyMonitorClient/plugins/linux/host_alive.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | 4 | 5 | import subprocess 6 | 7 | def monitor(frist_invoke=1): 8 | value_dic = {} 9 | shell_command = 'uptime' 10 | result = subprocess.Popen(shell_command,shell=True,stdout=subprocess.PIPE).stdout.read() 11 | 12 | #user,nice,system,iowait,steal,idle = result.split()[2:] 13 | value_dic= { 14 | 'uptime': result, 15 | 16 | 'status': 0 17 | } 18 | return value_dic 19 | 20 | 21 | print monitor() 22 | -------------------------------------------------------------------------------- /statics/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /CrazyMonitorClient/plugins/linux/network.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | 4 | import subprocess 5 | 6 | def monitor(frist_invoke=1): 7 | shell_command = 'sar -n DEV 1 5 |grep -v IFACE |grep Average' 8 | result = subprocess.Popen(shell_command,shell=True,stdout=subprocess.PIPE).stdout.readlines() 9 | #print(result) 10 | value_dic = {'status':0, 'data':{}} 11 | for line in result: 12 | line = line.split() 13 | nic_name,t_in,t_out = line[1],line[4],line[5] 14 | value_dic['data'][nic_name] = {"t_in":line[4], "t_out":line[5]} 15 | #print(value_dic) 16 | return value_dic -------------------------------------------------------------------------------- /monitor/backends/perpetual_machine.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | 4 | import sys,os 5 | import django 6 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 7 | sys.path.append(BASE_DIR) 8 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CrazyMonitor.settings") 9 | from CrazyMonitor import settings 10 | 11 | django.setup() 12 | from monitor import models 13 | from monitor.backends import data_processing 14 | 15 | 16 | 17 | if __name__ == '__main__': 18 | reactor = data_processing.DataHandler(settings) 19 | reactor.looping() 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /statics/js/holder.min.js: -------------------------------------------------------------------------------- 1 | 2 | 404 Not Found 3 | 4 |

404 Not Found

5 |
nginx
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /monitor/urls.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | from django.conf.urls import url 4 | 5 | from monitor import views 6 | 7 | urlpatterns = [ 8 | 9 | #url(r'^$',views.dashboard ), 10 | #url(r'^dashboard/$',views.dashboard ,name='dashboard' ), 11 | url(r'^triggers/$',views.triggers,name='triggers' ), 12 | url(r'hosts/$',views.hosts ,name='hosts'), 13 | url(r'host_groups/$',views.host_groups ,name='host_groups'), 14 | url(r'hosts/(\d+)/$',views.host_detail ,name='host_detail'), 15 | #url(r'graph/$',views.graph ,name='get_graph'), 16 | url(r'trigger_list/$',views.trigger_list ,name='trigger_list'), 17 | #url(r'client/service/report/$',views.service_data_report ) 18 | 19 | ] 20 | -------------------------------------------------------------------------------- /statics/js/ie10-viewport-bug-workaround.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * IE10 viewport hack for Surface/desktop Windows 8 bug 3 | * Copyright 2014-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | // See the Getting Started docs for more information: 8 | // http://getbootstrap.com/getting-started/#support-ie10-width 9 | 10 | (function () { 11 | 'use strict'; 12 | 13 | if (navigator.userAgent.match(/IEMobile\/10\.0/)) { 14 | var msViewportStyle = document.createElement('style') 15 | msViewportStyle.appendChild( 16 | document.createTextNode( 17 | '@-ms-viewport{width:auto!important}' 18 | ) 19 | ) 20 | document.querySelector('head').appendChild(msViewportStyle) 21 | } 22 | 23 | })(); 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CrazyMonitor 2 | 用python写的强大的分布式监控软件 3 | 参考zabbix,openfalcon架构,前端、后端、监控插件、画图、数据优化存储等全部自己实现,通过学习本项目可以了解复杂自动化项目的架构设计、程序解耦原则、前后端数据交互等多项实战技能。 4 | 5 | 6 | ## 启动 7 | 8 | python3 manage.py runserver 0.0.0.0:9000 启动监控服务web端 9 | 10 | python3 MonitorServer.py start 启动监控主程序 11 | 12 | python3 MonitorServer.py trigger_watch 启动报警监听程序 13 | 14 | 15 | # 项目讲解视频 16 | http://edu.51cto.com/course/course_id-6208.html 17 | # python自动化交流群 18 | Python开发之路 304154367 19 | 20 | 21 | # 项目截图 22 | ![image](https://github.com/triaquae/CrazyMonitor/blob/master/share/screeshots/flow.png) 23 | ![image](https://github.com/triaquae/CrazyMonitor/blob/master/share/screeshots/monitor1.png) 24 | ![image](https://github.com/triaquae/CrazyMonitor/blob/master/share/screeshots/monitor2.png) 25 | -------------------------------------------------------------------------------- /CrazyMonitorClient/plugins/plugin_api.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | 4 | from linux import sysinfo,load,cpu_mac,cpu,memory,network,host_alive 5 | 6 | 7 | 8 | def LinuxSysInfo(): 9 | #print __file__ 10 | return sysinfo.collect() 11 | 12 | 13 | def WindowsSysInfo(): 14 | from windows import sysinfo as win_sysinfo 15 | return win_sysinfo.collect() 16 | 17 | def get_linux_cpu(): 18 | return cpu.monitor() 19 | 20 | def host_alive_check(): 21 | return host_alive.monitor() 22 | 23 | def GetMacCPU(): 24 | #return cpu.monitor() 25 | return cpu_mac.monitor() 26 | 27 | def GetNetworkStatus(): 28 | return network.monitor() 29 | 30 | def get_memory_info(): 31 | return memory.monitor() 32 | 33 | 34 | def get_linux_load(): 35 | return load.monitor() -------------------------------------------------------------------------------- /CrazyMonitorClient/plugins/linux/cpu_mac.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #coding:utf-8 3 | 4 | #apt-get install sysstat 5 | 6 | import commands 7 | 8 | def monitor(frist_invoke=1): 9 | shell_command = 'sar 1 3| grep "^Average:"' 10 | status,result = commands.getstatusoutput(shell_command) 11 | if status != 0: 12 | value_dic = {'status': status} 13 | else: 14 | value_dic = {} 15 | #print('---res:',result) 16 | user,nice,system,idle = result.split()[1:] 17 | value_dic= { 18 | 'user': user, 19 | 'nice': nice, 20 | 'system': system, 21 | 'idle': idle, 22 | 'status': status 23 | } 24 | return value_dic 25 | 26 | if __name__ == '__main__': 27 | print monitor() 28 | -------------------------------------------------------------------------------- /.idea/dataSources.local.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | false 10 | true 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /CrazyMonitorClient/plugins/linux/mac_load.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #coding:utf-8 3 | 4 | 5 | import commands 6 | 7 | 8 | def monitor(): 9 | shell_command = 'uptime' 10 | 11 | status,result = commands.getstatusoutput(shell_command) 12 | if status != 0: #cmd exec error 13 | value_dic = {'status':status} 14 | else: 15 | value_dic = {} 16 | uptime = result.split(',')[:1][0] 17 | print(result) 18 | #load1,load5,load15 = result.split('load averages:')[1].split(',') 19 | load1,load5,load15 = result.split('load averages:')[1].split() 20 | value_dic= { 21 | #'uptime': uptime, 22 | 'load1': load1, 23 | 'load5': load5, 24 | 'load15': load15, 25 | 'status': status 26 | } 27 | return value_dic 28 | 29 | 30 | 31 | print(monitor()) 32 | -------------------------------------------------------------------------------- /statics/js/custom.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by jieli on 4/29/16. 3 | */ 4 | 5 | 6 | Date.prototype.format = function(format) { 7 | var o = { 8 | "M+": this.getMonth() + 1, 9 | // month 10 | "d+": this.getDate(), 11 | // day 12 | "h+": this.getHours(), 13 | // hour 14 | "m+": this.getMinutes(), 15 | // minute 16 | "s+": this.getSeconds(), 17 | // second 18 | "q+": Math.floor((this.getMonth() + 3) / 3), 19 | // quarter 20 | "S": this.getMilliseconds() 21 | // millisecond 22 | }; 23 | if (/(y+)/.test(format) || /(Y+)/.test(format)) { 24 | format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 25 | } 26 | for (var k in o) { 27 | if (new RegExp("(" + k + ")").test(format)) { 28 | format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)); 29 | } 30 | } 31 | return format; 32 | }; 33 | 34 | //usage: timestamp = (new Date(parseFloat(rData[7]))).format("yyyy-MM-dd hh:mm:ss"); -------------------------------------------------------------------------------- /CrazyMonitor/urls.py: -------------------------------------------------------------------------------- 1 | """CrazyMonitor URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.9/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.conf.urls import url, include 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 | """ 16 | from django.conf.urls import url,include 17 | from django.contrib import admin 18 | from monitor import views 19 | from monitor import api_urls 20 | 21 | urlpatterns = [ 22 | url(r'^admin/', admin.site.urls), 23 | url(r'^api/',include('monitor.api_urls')), 24 | url(r'^$',views.dashboard,name='dashboard' ), 25 | url(r'^monitor/',include('monitor.urls')), 26 | 27 | ] 28 | -------------------------------------------------------------------------------- /CrazyMonitorClient/core/main.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | 4 | import client 5 | class command_handler(object): 6 | 7 | def __init__(self, sys_args): 8 | self.sys_args = sys_args 9 | if len(self.sys_args)<2:exit(self.help_msg()) 10 | self.command_allowcator() 11 | 12 | 13 | def command_allowcator(self): 14 | '''分捡用户输入的不同指令''' 15 | print(self.sys_args[1]) 16 | 17 | if hasattr(self,self.sys_args[1]): 18 | func= getattr(self,self.sys_args[1]) 19 | return func() 20 | else: 21 | print("command does not exist!") 22 | self.help_msg() 23 | 24 | def help_msg(self): 25 | valid_commands = ''' 26 | start start monitor client 27 | stop stop monitor client 28 | 29 | ''' 30 | exit(valid_commands) 31 | 32 | 33 | def start(self): 34 | print("going to start the monitor client") 35 | #exit_flag = False 36 | 37 | Client = client.ClientHandle() 38 | Client.forever_run() 39 | 40 | def stop(self): 41 | print("stopping the monitor client") -------------------------------------------------------------------------------- /.idea/CrazyMonitor.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | 27 | 29 | -------------------------------------------------------------------------------- /monitor/auth.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'jieli' 3 | 4 | 5 | from django.db import models 6 | from django.contrib.auth.models import ( 7 | BaseUserManager, AbstractBaseUser,Group,PermissionsMixin 8 | ) 9 | import django 10 | 11 | class UserManager(BaseUserManager): 12 | def create_user(self, email, name, password=None): 13 | """ 14 | Creates and saves a User with the given email, date of 15 | birth and password. 16 | """ 17 | if not email: 18 | raise ValueError('Users must have an email address') 19 | 20 | user = self.model( 21 | email=self.normalize_email(email), 22 | name=name, 23 | 24 | ) 25 | 26 | user.set_password(password) 27 | user.save(using=self._db) 28 | return user 29 | 30 | def create_superuser(self, email, name ,password): 31 | """ 32 | Creates and saves a superuser with the given email, date of 33 | birth and password. 34 | """ 35 | user = self.create_user(email, 36 | password=password, 37 | name=name, 38 | ) 39 | user.is_admin = True 40 | user.save(using=self._db) 41 | return user 42 | 43 | 44 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/basic-line/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 40 | 41 | 42 | 43 | 44 | 45 |
46 | 47 | 48 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/spline/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 | 46 | 47 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/step-line/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 | 46 | 47 | -------------------------------------------------------------------------------- /monitor/migrations/0002_auto_20170407_1608.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.2 on 2017-04-07 08:08 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.db.models.deletion 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('monitor', '0001_initial'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='EventLog', 18 | fields=[ 19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('event_type', models.SmallIntegerField(choices=[(0, '报警事件'), (1, '维护事件')], default=0)), 21 | ('log', models.TextField(blank=True, null=True)), 22 | ('date', models.DateTimeField(auto_now_add=True)), 23 | ('host', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='monitor.Host')), 24 | ('trigger', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='monitor.Trigger')), 25 | ], 26 | ), 27 | migrations.AlterField( 28 | model_name='actionoperation', 29 | name='step', 30 | field=models.SmallIntegerField(default=1, help_text='当trigger触发次数小于这个值时就执行这条记录里报警方式', verbose_name='第n次告警'), 31 | ), 32 | ] 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | -------------------------------------------------------------------------------- /.idea/dataSources.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | sqlite.xerial 6 | true 7 | true 8 | SQLite 9 | org.sqlite.JDBC 10 | jdbc:sqlite:$PROJECT_DIR$/monitor_db.sqlite3 11 | 12 | 13 | sqlite.xerial 14 | true 15 | true 16 | $PROJECT_DIR$/CrazyMonitor/settings.py 17 | org.sqlite.JDBC 18 | jdbc:sqlite:$PROJECT_DIR$/monitor_db.sqlite3 19 | 20 | 21 | sqlite.xerial 22 | true 23 | true 24 | SQLite 25 | org.sqlite.JDBC 26 | jdbc:sqlite:$PROJECT_DIR$/monitor_db.sqlite3 27 | 28 | 29 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/navigator-disabled/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
50 | 51 | 52 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/scrollbar-disabled/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
50 | 51 | 52 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/modules/no-data-to-display.js: -------------------------------------------------------------------------------- 1 | /* 2 | Highstock JS v4.2.4 (2016-04-14) 3 | Plugin for displaying a message when there is no data visible in chart. 4 | 5 | (c) 2010-2016 Highsoft AS 6 | Author: Oystein Moseng 7 | 8 | License: www.highcharts.com/license 9 | */ 10 | (function(a){typeof module==="object"&&module.exports?module.exports=a:a(Highcharts)})(function(a){function h(){return!!this.points.length}function d(){this.hasData()?this.hideNoData():this.showNoData()}var e=a.seriesTypes,c=a.Chart.prototype,f=a.getOptions(),g=a.extend,i=a.each;g(f.lang,{noData:"No data to display"});f.noData={position:{x:0,y:0,align:"center",verticalAlign:"middle"},attr:{},style:{fontWeight:"bold",fontSize:"12px",color:"#60606a"}};i(["pie","gauge","waterfall","bubble","treemap"], 11 | function(b){if(e[b])e[b].prototype.hasData=h});a.Series.prototype.hasData=function(){return this.visible&&this.dataMax!==void 0&&this.dataMin!==void 0};c.showNoData=function(b){var a=this.options,b=b||a.lang.noData,a=a.noData;if(!this.noDataLabel)this.noDataLabel=this.renderer.label(b,0,0,null,null,null,a.useHTML,null,"no-data").attr(a.attr).css(a.style).add(),this.noDataLabel.align(g(this.noDataLabel.getBBox(),a.position),!1,"plotBox")};c.hideNoData=function(){if(this.noDataLabel)this.noDataLabel= 12 | this.noDataLabel.destroy()};c.hasData=function(){for(var a=this.series,c=a.length;c--;)if(a[c].hasData()&&!a[c].options.isInternal)return!0;return!1};c.callbacks.push(function(b){a.addEvent(b,"load",d);a.addEvent(b,"redraw",d)})}); 13 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/markers-only/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
51 | 52 | 53 | -------------------------------------------------------------------------------- /CrazyMonitorClient/plugins/linux/memory.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #coding:utf-8 3 | 4 | 5 | import commands 6 | 7 | 8 | def monitor(frist_invoke=1): 9 | monitor_dic = { 10 | 'SwapUsage': 'percentage', 11 | 'MemUsage' : 'percentage', 12 | } 13 | shell_command ="grep 'MemTotal\|MemFree\|Buffers\|^Cached\|SwapTotal\|SwapFree' /proc/meminfo" 14 | 15 | status,result = commands.getstatusoutput(shell_command) 16 | if status != 0: #cmd exec error 17 | value_dic = {'status':status} 18 | else: 19 | value_dic = {'status':status} 20 | for i in result.split('kB\n'): 21 | key= i.split()[0].strip(':') # factor name 22 | value = i.split()[1] # factor value 23 | value_dic[ key] = value 24 | 25 | if monitor_dic['SwapUsage'] == 'percentage': 26 | value_dic['SwapUsage_p'] = str(100 - int(value_dic['SwapFree']) * 100 / int(value_dic['SwapTotal'])) 27 | #real SwapUsage value 28 | value_dic['SwapUsage'] = int(value_dic['SwapTotal']) - int(value_dic['SwapFree']) 29 | 30 | MemUsage = int(value_dic['MemTotal']) - (int(value_dic['MemFree']) + int(value_dic['Buffers']) + int(value_dic['Cached'])) 31 | if monitor_dic['MemUsage'] == 'percentage': 32 | value_dic['MemUsage_p'] = str(int(MemUsage) * 100 / int(value_dic['MemTotal'])) 33 | #real MemUsage value 34 | value_dic['MemUsage'] = MemUsage 35 | return value_dic 36 | 37 | if __name__ == '__main__': 38 | print monitor() 39 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/line-markers/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
51 | 52 | 53 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/themes/grid-light.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Grid-light theme for Highcharts JS 3 | * @author Torstein Honsi 4 | */ 5 | 6 | // Load the fonts 7 | Highcharts.createElement('link', { 8 | href: '//fonts.googleapis.com/css?family=Dosis:400,600', 9 | rel: 'stylesheet', 10 | type: 'text/css' 11 | }, null, document.getElementsByTagName('head')[0]); 12 | 13 | Highcharts.theme = { 14 | colors: ["#7cb5ec", "#f7a35c", "#90ee7e", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee", 15 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"], 16 | chart: { 17 | backgroundColor: null, 18 | style: { 19 | fontFamily: "Dosis, sans-serif" 20 | } 21 | }, 22 | title: { 23 | style: { 24 | fontSize: '16px', 25 | fontWeight: 'bold', 26 | textTransform: 'uppercase' 27 | } 28 | }, 29 | tooltip: { 30 | borderWidth: 0, 31 | backgroundColor: 'rgba(219,219,216,0.8)', 32 | shadow: false 33 | }, 34 | legend: { 35 | itemStyle: { 36 | fontWeight: 'bold', 37 | fontSize: '13px' 38 | } 39 | }, 40 | xAxis: { 41 | gridLineWidth: 1, 42 | labels: { 43 | style: { 44 | fontSize: '12px' 45 | } 46 | } 47 | }, 48 | yAxis: { 49 | minorTickInterval: 'auto', 50 | title: { 51 | style: { 52 | textTransform: 'uppercase' 53 | } 54 | }, 55 | labels: { 56 | style: { 57 | fontSize: '12px' 58 | } 59 | } 60 | }, 61 | plotOptions: { 62 | candlestick: { 63 | lineColor: '#404048' 64 | } 65 | }, 66 | 67 | 68 | // General 69 | background2: '#F0F0EA' 70 | 71 | }; 72 | 73 | // Apply the theme 74 | Highcharts.setOptions(Highcharts.theme); 75 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/arearange/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/columnrange/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/areasplinerange/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /templates/monitor/trigger_list.html: -------------------------------------------------------------------------------- 1 | {% load custom_tags %} 2 |
3 |
4 |
5 |
6 |

Hover rows

7 |
8 | 9 | 10 | 11 |
12 | {{ trigger_list }} 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | {% for alert in alert_list %} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | {% endfor %} 33 | 34 |
事件类型级别内容日期
{{ alert.get_event_type_display }}{{ alert.trigger }}{{ alert.log }}{{ alert.date }}
35 |
36 | 37 | 38 | 39 |
40 |
41 |
-------------------------------------------------------------------------------- /statics/plugins/highstock/examples/ohlc/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
53 | 54 | 55 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/column/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
54 | 55 | 56 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/candlestick/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 48 | 49 | 50 | 51 | 52 | 53 |
54 | 55 | 56 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/styled-scrollbar/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 50 | 51 | 52 | 53 | 54 | 55 | 56 |
57 | 58 | 59 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/intraday-candlestick/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 54 | 55 | 56 |
57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/area/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 | 61 | 62 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/areaspline/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 | 61 | 62 | -------------------------------------------------------------------------------- /monitor/templatetags/custom_tags.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | from django import template 4 | from monitor import models 5 | from django.utils.safestring import mark_safe 6 | 7 | register = template.Library() 8 | 9 | @register.simple_tag 10 | def trigger_context(data): 11 | expressions = data['positive_expressions'] 12 | 13 | html = '' 14 | for expression_item in expressions: 15 | expression_obj = models.TriggerExpression.objects.get(id=expression_item['expression_obj']) 16 | line ='''

service:{service} index:{service_index} operator:{operator} func:{calc_func} args:{calc_args} 17 | threshold:{threshold} calc_res:{calc_res} real_val:{real_val} 18 |

'''.format(service=expression_obj.service.name, 19 | service_index=expression_obj.service_index.name, 20 | operator=expression_obj.operator_type, 21 | calc_func=expression_obj.data_calc_func, 22 | calc_args=expression_obj.data_calc_args, 23 | threshold=expression_obj.threshold, 24 | calc_res=expression_item.get('calc_res'), 25 | real_val = expression_item.get('calc_res_val') 26 | ) 27 | html +=line 28 | 29 | return mark_safe(html) 30 | 31 | 32 | 33 | 34 | @register.simple_tag 35 | def get_trigger_severity_color(alert_obj): 36 | severity_choices = { 37 | 1:'white', 38 | 2:'yellow', 39 | 3:'orange', 40 | 4:'red', 41 | 5:'darkred', 42 | } 43 | 44 | return severity_choices.get(alert_obj.trigger.severity) or '' -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/yaxis-reversed/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/themes/skies.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Skies theme for Highcharts JS 3 | * @author Torstein Honsi 4 | */ 5 | 6 | Highcharts.theme = { 7 | colors: ["#514F78", "#42A07B", "#9B5E4A", "#72727F", "#1F949A", "#82914E", "#86777F", "#42A07B"], 8 | chart: { 9 | className: 'skies', 10 | borderWidth: 0, 11 | plotShadow: true, 12 | plotBackgroundImage: 'http://www.highcharts.com/demo/gfx/skies.jpg', 13 | plotBackgroundColor: { 14 | linearGradient: [0, 0, 250, 500], 15 | stops: [ 16 | [0, 'rgba(255, 255, 255, 1)'], 17 | [1, 'rgba(255, 255, 255, 0)'] 18 | ] 19 | }, 20 | plotBorderWidth: 1 21 | }, 22 | title: { 23 | style: { 24 | color: '#3E576F', 25 | font: '16px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 26 | } 27 | }, 28 | subtitle: { 29 | style: { 30 | color: '#6D869F', 31 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 32 | } 33 | }, 34 | xAxis: { 35 | gridLineWidth: 0, 36 | lineColor: '#C0D0E0', 37 | tickColor: '#C0D0E0', 38 | labels: { 39 | style: { 40 | color: '#666', 41 | fontWeight: 'bold' 42 | } 43 | }, 44 | title: { 45 | style: { 46 | color: '#666', 47 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 48 | } 49 | } 50 | }, 51 | yAxis: { 52 | alternateGridColor: 'rgba(255, 255, 255, .5)', 53 | lineColor: '#C0D0E0', 54 | tickColor: '#C0D0E0', 55 | tickWidth: 1, 56 | labels: { 57 | style: { 58 | color: '#666', 59 | fontWeight: 'bold' 60 | } 61 | }, 62 | title: { 63 | style: { 64 | color: '#666', 65 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 66 | } 67 | } 68 | }, 69 | legend: { 70 | itemStyle: { 71 | font: '9pt Trebuchet MS, Verdana, sans-serif', 72 | color: '#3E576F' 73 | }, 74 | itemHoverStyle: { 75 | color: 'black' 76 | }, 77 | itemHiddenStyle: { 78 | color: 'silver' 79 | } 80 | }, 81 | labels: { 82 | style: { 83 | color: '#3E576F' 84 | } 85 | } 86 | }; 87 | 88 | // Apply the theme 89 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme); 90 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/themes/sand-signika.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sand-Signika theme for Highcharts JS 3 | * @author Torstein Honsi 4 | */ 5 | 6 | // Load the fonts 7 | Highcharts.createElement('link', { 8 | href: '//fonts.googleapis.com/css?family=Signika:400,700', 9 | rel: 'stylesheet', 10 | type: 'text/css' 11 | }, null, document.getElementsByTagName('head')[0]); 12 | 13 | // Add the background image to the container 14 | Highcharts.wrap(Highcharts.Chart.prototype, 'getContainer', function (proceed) { 15 | proceed.call(this); 16 | this.container.style.background = 'url(http://www.highcharts.com/samples/graphics/sand.png)'; 17 | }); 18 | 19 | 20 | Highcharts.theme = { 21 | colors: ["#f45b5b", "#8085e9", "#8d4654", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee", 22 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"], 23 | chart: { 24 | backgroundColor: null, 25 | style: { 26 | fontFamily: "Signika, serif" 27 | } 28 | }, 29 | title: { 30 | style: { 31 | color: 'black', 32 | fontSize: '16px', 33 | fontWeight: 'bold' 34 | } 35 | }, 36 | subtitle: { 37 | style: { 38 | color: 'black' 39 | } 40 | }, 41 | tooltip: { 42 | borderWidth: 0 43 | }, 44 | legend: { 45 | itemStyle: { 46 | fontWeight: 'bold', 47 | fontSize: '13px' 48 | } 49 | }, 50 | xAxis: { 51 | labels: { 52 | style: { 53 | color: '#6e6e70' 54 | } 55 | } 56 | }, 57 | yAxis: { 58 | labels: { 59 | style: { 60 | color: '#6e6e70' 61 | } 62 | } 63 | }, 64 | plotOptions: { 65 | series: { 66 | shadow: true 67 | }, 68 | candlestick: { 69 | lineColor: '#404048' 70 | }, 71 | map: { 72 | shadow: false 73 | } 74 | }, 75 | 76 | // Highstock specific 77 | navigator: { 78 | xAxis: { 79 | gridLineColor: '#D0D0D8' 80 | } 81 | }, 82 | rangeSelector: { 83 | buttonTheme: { 84 | fill: 'white', 85 | stroke: '#C0C0C8', 86 | 'stroke-width': 1, 87 | states: { 88 | select: { 89 | fill: '#D0D0D8' 90 | } 91 | } 92 | } 93 | }, 94 | scrollbar: { 95 | trackBorderColor: '#C0C0C8' 96 | }, 97 | 98 | // General 99 | background2: '#E0E0E8' 100 | 101 | }; 102 | 103 | // Apply the theme 104 | Highcharts.setOptions(Highcharts.theme); 105 | -------------------------------------------------------------------------------- /statics/js/ie-emulation-modes-warning.js: -------------------------------------------------------------------------------- 1 | // NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT 2 | // IT'S JUST JUNK FOR OUR DOCS! 3 | // ++++++++++++++++++++++++++++++++++++++++++ 4 | /*! 5 | * Copyright 2014-2015 Twitter, Inc. 6 | * 7 | * Licensed under the Creative Commons Attribution 3.0 Unported License. For 8 | * details, see https://creativecommons.org/licenses/by/3.0/. 9 | */ 10 | // Intended to prevent false-positive bug reports about Bootstrap not working properly in old versions of IE due to folks testing using IE's unreliable emulation modes. 11 | (function () { 12 | 'use strict'; 13 | 14 | function emulatedIEMajorVersion() { 15 | var groups = /MSIE ([0-9.]+)/.exec(window.navigator.userAgent) 16 | if (groups === null) { 17 | return null 18 | } 19 | var ieVersionNum = parseInt(groups[1], 10) 20 | var ieMajorVersion = Math.floor(ieVersionNum) 21 | return ieMajorVersion 22 | } 23 | 24 | function actualNonEmulatedIEMajorVersion() { 25 | // Detects the actual version of IE in use, even if it's in an older-IE emulation mode. 26 | // IE JavaScript conditional compilation docs: https://msdn.microsoft.com/library/121hztk3%28v=vs.94%29.aspx 27 | // @cc_on docs: https://msdn.microsoft.com/library/8ka90k2e%28v=vs.94%29.aspx 28 | var jscriptVersion = new Function('/*@cc_on return @_jscript_version; @*/')() // jshint ignore:line 29 | if (jscriptVersion === undefined) { 30 | return 11 // IE11+ not in emulation mode 31 | } 32 | if (jscriptVersion < 9) { 33 | return 8 // IE8 (or lower; haven't tested on IE<8) 34 | } 35 | return jscriptVersion // IE9 or IE10 in any mode, or IE11 in non-IE11 mode 36 | } 37 | 38 | var ua = window.navigator.userAgent 39 | if (ua.indexOf('Opera') > -1 || ua.indexOf('Presto') > -1) { 40 | return // Opera, which might pretend to be IE 41 | } 42 | var emulated = emulatedIEMajorVersion() 43 | if (emulated === null) { 44 | return // Not IE 45 | } 46 | var nonEmulated = actualNonEmulatedIEMajorVersion() 47 | 48 | if (emulated !== nonEmulated) { 49 | window.alert('WARNING: You appear to be using IE' + nonEmulated + ' in IE' + emulated + ' emulation mode.\nIE emulation modes can behave significantly differently from ACTUAL older versions of IE.\nPLEASE DON\'T FILE BOOTSTRAP BUGS based on testing in IE emulation modes!') 50 | } 51 | })(); 52 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/themes/grid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Grid theme for Highcharts JS 3 | * @author Torstein Honsi 4 | */ 5 | 6 | Highcharts.theme = { 7 | colors: ['#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4'], 8 | chart: { 9 | backgroundColor: { 10 | linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 }, 11 | stops: [ 12 | [0, 'rgb(255, 255, 255)'], 13 | [1, 'rgb(240, 240, 255)'] 14 | ] 15 | }, 16 | borderWidth: 2, 17 | plotBackgroundColor: 'rgba(255, 255, 255, .9)', 18 | plotShadow: true, 19 | plotBorderWidth: 1 20 | }, 21 | title: { 22 | style: { 23 | color: '#000', 24 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif' 25 | } 26 | }, 27 | subtitle: { 28 | style: { 29 | color: '#666666', 30 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif' 31 | } 32 | }, 33 | xAxis: { 34 | gridLineWidth: 1, 35 | lineColor: '#000', 36 | tickColor: '#000', 37 | labels: { 38 | style: { 39 | color: '#000', 40 | font: '11px Trebuchet MS, Verdana, sans-serif' 41 | } 42 | }, 43 | title: { 44 | style: { 45 | color: '#333', 46 | fontWeight: 'bold', 47 | fontSize: '12px', 48 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 49 | 50 | } 51 | } 52 | }, 53 | yAxis: { 54 | minorTickInterval: 'auto', 55 | lineColor: '#000', 56 | lineWidth: 1, 57 | tickWidth: 1, 58 | tickColor: '#000', 59 | labels: { 60 | style: { 61 | color: '#000', 62 | font: '11px Trebuchet MS, Verdana, sans-serif' 63 | } 64 | }, 65 | title: { 66 | style: { 67 | color: '#333', 68 | fontWeight: 'bold', 69 | fontSize: '12px', 70 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 71 | } 72 | } 73 | }, 74 | legend: { 75 | itemStyle: { 76 | font: '9pt Trebuchet MS, Verdana, sans-serif', 77 | color: 'black' 78 | 79 | }, 80 | itemHoverStyle: { 81 | color: '#039' 82 | }, 83 | itemHiddenStyle: { 84 | color: 'gray' 85 | } 86 | }, 87 | labels: { 88 | style: { 89 | color: '#99b' 90 | } 91 | }, 92 | 93 | navigation: { 94 | buttonOptions: { 95 | theme: { 96 | stroke: '#CCCCCC' 97 | } 98 | } 99 | } 100 | }; 101 | 102 | // Apply the theme 103 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme); 104 | -------------------------------------------------------------------------------- /templates/monitor/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | CrazyMonitor | Oldboy edu 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | {% block content-container %} 51 | put your page content here 52 | {% endblock %} 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 81 | {% block bottom-js %} 82 | 83 | {% endblock %} 84 | 85 | 86 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/modules/funnel.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Highcharts funnel module 4 | 5 | (c) 2010-2016 Torstein Honsi 6 | 7 | License: www.highcharts.com/license 8 | */ 9 | (function(b){typeof module==="object"&&module.exports?module.exports=b:b(Highcharts)})(function(b){var q=b.getOptions(),w=q.plotOptions,r=b.seriesTypes,F=b.merge,E=function(){},B=b.each;w.funnel=F(w.pie,{animation:!1,center:["50%","50%"],width:"90%",neckWidth:"30%",height:"100%",neckHeight:"25%",reversed:!1,dataLabels:{connectorWidth:1,connectorColor:"#606060"},size:!0,states:{select:{color:"#C0C0C0",borderColor:"#000000",shadow:!1}}});r.funnel=b.extendClass(r.pie,{type:"funnel",animate:E,translate:function(){var a= 10 | function(k,a){return/%$/.test(k)?a*parseInt(k,10)/100:parseInt(k,10)},b=0,d=this.chart,c=this.options,f=c.reversed,g=c.ignoreHiddenPoint,o=d.plotWidth,h=d.plotHeight,q=0,d=c.center,i=a(d[0],o),x=a(d[1],h),r=a(c.width,o),l,s,e=a(c.height,h),t=a(c.neckWidth,o),C=a(c.neckHeight,h),u=x-e/2+e-C,a=this.data,y,z,w=c.dataLabels.position==="left"?1:0,A,m,D,p,j,v,n;this.getWidthAt=s=function(k){var a=x-e/2;return k>u||e===C?t:t+(r-t)*(1-(k-a)/(e-C))};this.getX=function(k,a){return i+(a?-1:1)*(s(f?h-k:k)/2+ 11 | c.dataLabels.distance)};this.center=[i,x,e];this.centerX=i;B(a,function(a){if(!g||a.visible!==!1)b+=a.y});B(a,function(a){n=null;z=b?a.y/b:0;m=x-e/2+q*e;j=m+z*e;l=s(m);A=i-l/2;D=A+l;l=s(j);p=i-l/2;v=p+l;m>u?(A=p=i-t/2,D=v=i+t/2):j>u&&(n=j,l=s(u),p=i-l/2,v=p+l,j=u);f&&(m=e-m,j=e-j,n=n?e-n:null);y=["M",A,m,"L",D,m,v,j];n&&y.push(v,n,p,n);y.push(p,j,"Z");a.shapeType="path";a.shapeArgs={d:y};a.percentage=z*100;a.plotX=i;a.plotY=(m+(n||j))/2;a.tooltipPos=[i,a.plotY];a.slice=E;a.half=w;if(!g||a.visible!== 12 | !1)q+=z})},drawPoints:function(){var a=this,b=a.chart.renderer,d,c,f;B(a.data,function(g){f=g.graphic;c=g.shapeArgs;d=g.pointAttr[g.selected?"select":""];f?f.attr(d).animate(c):g.graphic=b.path(c).attr(d).add(a.group)})},sortByAngle:function(a){a.sort(function(a,b){return a.plotY-b.plotY})},drawDataLabels:function(){var a=this.data,b=this.options.dataLabels.distance,d,c,f,g=a.length,o,h;for(this.center[2]-=2*b;g--;)f=a[g],c=(d=f.half)?1:-1,h=f.plotY,o=this.getX(h,d),f.labelPos=[0,h,o+(b-5)*c,h,o+ 13 | b*c,h,d?"right":"left",0];r.pie.prototype.drawDataLabels.call(this)}});q.plotOptions.pyramid=b.merge(q.plotOptions.funnel,{neckWidth:"0%",neckHeight:"0%",reversed:!0});b.seriesTypes.pyramid=b.extendClass(b.seriesTypes.funnel,{type:"pyramid"})}); 14 | -------------------------------------------------------------------------------- /statics/css/dashboard.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Base structure 3 | */ 4 | 5 | /* Move down content because we have a fixed navbar that is 50px tall */ 6 | body { 7 | padding-top: 50px; 8 | } 9 | 10 | 11 | /* 12 | * Global add-ons 13 | */ 14 | 15 | .sub-header { 16 | padding-bottom: 10px; 17 | border-bottom: 1px solid #eee; 18 | } 19 | 20 | /* 21 | * Top navigation 22 | * Hide default border to remove 1px line. 23 | */ 24 | .navbar-fixed-top { 25 | border: 0; 26 | } 27 | 28 | /* 29 | * Sidebar 30 | */ 31 | 32 | /* Hide for mobile, show later */ 33 | .sidebar { 34 | display: none; 35 | } 36 | @media (min-width: 768px) { 37 | .sidebar { 38 | position: fixed; 39 | top: 51px; 40 | bottom: 0; 41 | left: 0; 42 | z-index: 1000; 43 | display: block; 44 | padding: 20px; 45 | overflow-x: hidden; 46 | overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */ 47 | background-color: #f5f5f5; 48 | border-right: 1px solid #eee; 49 | } 50 | } 51 | 52 | /* Sidebar navigation */ 53 | .nav-sidebar { 54 | margin-right: -21px; /* 20px padding + 1px border */ 55 | margin-bottom: 20px; 56 | margin-left: -20px; 57 | } 58 | .nav-sidebar > li > a { 59 | padding-right: 20px; 60 | padding-left: 20px; 61 | } 62 | .nav-sidebar > .active > a, 63 | .nav-sidebar > .active > a:hover, 64 | .nav-sidebar > .active > a:focus { 65 | color: #fff; 66 | background-color: #428bca; 67 | } 68 | 69 | 70 | /* 71 | * Main content 72 | */ 73 | 74 | .main { 75 | padding: 20px; 76 | } 77 | @media (min-width: 768px) { 78 | .main { 79 | padding-right: 40px; 80 | padding-left: 40px; 81 | } 82 | } 83 | .main .page-header { 84 | margin-top: 0; 85 | } 86 | 87 | 88 | /* 89 | * Placeholder dashboard ideas 90 | */ 91 | 92 | .placeholders { 93 | margin-bottom: 30px; 94 | text-align: center; 95 | } 96 | .placeholders h4 { 97 | margin-bottom: 0; 98 | } 99 | .placeholder { 100 | margin-bottom: 20px; 101 | } 102 | .placeholder img { 103 | display: inline-block; 104 | border-radius: 50%; 105 | } 106 | 107 | 108 | 109 | 110 | /* customize css*/ 111 | 112 | .css-success{ 113 | background-color: lightgreen; 114 | } 115 | .css-danger{ 116 | background-color: red; 117 | } 118 | .css-warning{ 119 | background-color: orangered; 120 | } 121 | .css-default{ 122 | background-color: lightgray; 123 | } -------------------------------------------------------------------------------- /monitor/backends/management.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | 4 | import os,sys 5 | #from perpetual_machine import 6 | import django 7 | django.setup() 8 | from monitor.backends import data_processing,trigger_handler 9 | from CrazyMonitor import settings 10 | 11 | 12 | 13 | class ManagementUtility(object): 14 | """ 15 | Encapsulates the logic of the django-admin and manage.py utilities. 16 | 17 | A ManagementUtility has a number of commands, which can be manipulated 18 | by editing the self.commands dictionary. 19 | """ 20 | def __init__(self, argv=None): 21 | self.argv = argv or sys.argv[:] 22 | self.prog_name = os.path.basename(self.argv[0]) 23 | self.settings_exception = None 24 | self.registered_actions = { 25 | 'start':self.start, 26 | 'stop': self.stop, 27 | 'trigger_watch':self.trigger_watch, 28 | } 29 | 30 | self.argv_check() 31 | 32 | def argv_check(self): 33 | ''' 34 | do basic validation argv checks 35 | :return: 36 | ''' 37 | if len(self.argv) < 2: 38 | self.main_help_text() 39 | if self.argv[1] not in self.registered_actions: 40 | self.main_help_text() 41 | else: 42 | self.registered_actions[sys.argv[1]]() 43 | 44 | def start(self): 45 | '''start monitor server frontend and backend''' 46 | reactor = data_processing.DataHandler(settings) 47 | reactor.looping() 48 | 49 | def stop(self): 50 | '''stop monitor server''' 51 | 52 | def trigger_watch(self): 53 | '''start to listen triggers''' 54 | trigger_watch = trigger_handler.TriggerHandler(settings) 55 | trigger_watch.start_watching() 56 | 57 | def main_help_text(self, commands_only=False): 58 | """ 59 | Returns the script's main help text, as a string. 60 | """ 61 | if not commands_only: 62 | print("supported commands as flow:") 63 | for k,v in self.registered_actions.items(): 64 | print(" %s%s" % (k.ljust(20),v.__doc__)) 65 | exit() 66 | 67 | 68 | def execute(self): 69 | ''' 70 | run according to user's input 71 | :return: 72 | ''' 73 | def execute_from_command_line(argv=None): 74 | """ 75 | A simple method that runs a ManagementUtility. 76 | """ 77 | utility = ManagementUtility(argv) 78 | utility.execute() 79 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/flags-placement/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 70 | 71 | 72 | 73 | 74 | 75 | 76 |
77 | 78 | 79 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/intraday-area/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 76 | 77 | 78 |
79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/dynamic-update/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 82 | 83 | 84 | 85 | 86 | 87 |
88 | 89 | 90 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/compare/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 78 | 79 | 80 | 81 | 82 | 83 | 84 |
85 | 86 | 87 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/yaxis-plotbands/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 76 | 77 | 78 | 79 | 80 | 81 | 82 |
83 | 84 | 85 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/intraday-breaks/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 84 | 85 | 86 |
87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/modules/solid-gauge.js: -------------------------------------------------------------------------------- 1 | /* 2 | Highstock JS v4.2.4 (2016-04-14) 3 | Solid angular gauge module 4 | 5 | (c) 2010-2016 Torstein Honsi 6 | 7 | License: www.highcharts.com/license 8 | */ 9 | (function(a){typeof module==="object"&&module.exports?module.exports=a:a(Highcharts)})(function(a){var q=a.getOptions().plotOptions,r=a.pInt,s=a.pick,k=a.each,l;q.solidgauge=a.merge(q.gauge,{colorByPoint:!0});l={initDataClasses:function(b){var e=this,i=this.chart,c,g=0,d=this.options;this.dataClasses=c=[];k(b.dataClasses,function(f,h){var p,f=a.merge(f);c.push(f);if(!f.color)d.dataClassColor==="category"?(p=i.options.colors,f.color=p[g++],g===p.length&&(g=0)):f.color=e.tweenColors(a.Color(d.minColor), 10 | a.Color(d.maxColor),h/(b.dataClasses.length-1))})},initStops:function(b){this.stops=b.stops||[[0,this.options.minColor],[1,this.options.maxColor]];k(this.stops,function(b){b.color=a.Color(b[1])})},toColor:function(b,e){var a,c=this.stops,g,d=this.dataClasses,f,h;if(d)for(h=d.length;h--;){if(f=d[h],g=f.from,c=f.to,(g===void 0||b>=g)&&(c===void 0||b<=c)){a=f.color;if(e)e.dataClass=h;break}}else{this.isLog&&(b=this.val2lin(b));a=1-(this.max-b)/(this.max-this.min);for(h=c.length;h--;)if(a>c[h][0])break; 11 | g=c[h]||c[h+1];c=c[h+1]||g;a=1-(c[0]-a)/(c[0]-g[0]||1);a=this.tweenColors(g.color,c.color,a)}return a},tweenColors:function(b,a,i){var c;!a.rgba.length||!b.rgba.length?b=a.input||"none":(b=b.rgba,a=a.rgba,c=a[3]!==1||b[3]!==1,b=(c?"rgba(":"rgb(")+Math.round(a[0]+(b[0]-a[0])*(1-i))+","+Math.round(a[1]+(b[1]-a[1])*(1-i))+","+Math.round(a[2]+(b[2]-a[2])*(1-i))+(c?","+(a[3]+(b[3]-a[3])*(1-i)):"")+")");return b}};k(["fill","stroke"],function(b){a.Fx.prototype[b+"Setter"]=function(){this.elem.attr(b,l.tweenColors(a.Color(this.start), 12 | a.Color(this.end),this.pos))}});a.seriesTypes.solidgauge=a.extendClass(a.seriesTypes.gauge,{type:"solidgauge",pointAttrToOptions:{},bindAxes:function(){var b;a.seriesTypes.gauge.prototype.bindAxes.call(this);b=this.yAxis;a.extend(b,l);b.options.dataClasses&&b.initDataClasses(b.options);b.initStops(b.options)},drawPoints:function(){var b=this,e=b.yAxis,i=e.center,c=b.options,g=b.chart.renderer,d=c.overshoot,f=d&&typeof d==="number"?d/180*Math.PI:0;a.each(b.points,function(a){var d=a.graphic,j=e.startAngleRad+ 13 | e.translate(a.y,null,null,null,!0),k=r(s(a.options.radius,c.radius,100))*i[2]/200,m=r(s(a.options.innerRadius,c.innerRadius,60))*i[2]/200,n=e.toColor(a.y,a),o=Math.min(e.startAngleRad,e.endAngleRad),l=Math.max(e.startAngleRad,e.endAngleRad);n==="none"&&(n=a.color||b.color||"none");if(n!=="none")a.color=n;j=Math.max(o-f,Math.min(l+f,j));c.wrap===!1&&(j=Math.max(o,Math.min(l,j)));o=Math.min(j,e.startAngleRad);j=Math.max(j,e.startAngleRad);j-o>2*Math.PI&&(j=o+2*Math.PI);a.shapeArgs=m={x:i[0],y:i[1], 14 | r:k,innerR:m,start:o,end:j,fill:n};a.startR=k;if(d){if(a=m.d,d.animate(m),a)m.d=a}else d={stroke:c.borderColor||"none","stroke-width":c.borderWidth||0,fill:n,"sweep-flag":0},c.linecap!=="square"&&(d["stroke-linecap"]=d["stroke-linejoin"]="round"),a.graphic=g.arc(m).attr(d).add(b.group)})},animate:function(b){if(!b)this.startAngleRad=this.yAxis.startAngleRad,a.seriesTypes.pie.prototype.animate.call(this,b)}})}); 15 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/flags-general/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 83 | 84 | 85 | 86 | 87 | 88 | 89 |
90 | 91 | 92 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/yaxis-plotlines/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 85 | 86 | 87 | 88 | 89 | 90 | 91 |
92 | 93 | 94 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/data-grouping/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 92 | 93 | 94 | 95 | 96 | 97 |
98 | 99 | 100 | -------------------------------------------------------------------------------- /statics/plugins/highstock/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Examples 6 | 7 | 8 |

Highstock Examples

9 |

General

10 | 22 |

Chart types

23 | 37 |

Various features

38 | 46 |

Flags

47 | 51 |

更多在线实例:Highstock在线演示

Power by Highcharts中文网

52 | 53 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/modules/offline-exporting.js: -------------------------------------------------------------------------------- 1 | /* 2 | Highstock JS v4.2.4 (2016-04-14) 3 | Client side exporting module 4 | 5 | (c) 2015 Torstein Honsi / Oystein Moseng 6 | 7 | License: www.highcharts.com/license 8 | */ 9 | (function(c){typeof module==="object"&&module.exports?module.exports=c:c(Highcharts)})(function(c){function y(c,e){var i=l.getElementsByTagName("head")[0],b=l.createElement("script");b.type="text/javascript";b.src=c;b.onload=e;i.appendChild(b)}var e=c.win,g=e.navigator,l=e.document;c.CanVGRenderer={};c.Chart.prototype.exportChartLocal=function(z,A){var i=this,b=c.merge(i.options.exporting,z),B=g.userAgent.indexOf("WebKit")>-1&&g.userAgent.indexOf("Chrome")<0,n=b.scale||2,p,s=e.URL||e.webkitURL||e, 10 | k,t=0,q,o,u,d=function(){if(b.fallbackToExportServer===!1)if(b.error)b.error();else throw"Fallback to export server disabled";else i.exportChart(b)},v=function(a,j,f,b,m,c,d){var h=new e.Image,i,g=function(){var b=l.createElement("canvas"),c=b.getContext&&b.getContext("2d"),e;try{if(c){b.height=h.height*n;b.width=h.width*n;c.drawImage(h,0,0,b.width,b.height);try{e=b.toDataURL(),f(e,j)}catch(g){if(g.name==="SecurityError"||g.name==="SECURITY_ERR"||g.message==="SecurityError")i(a,j);else throw g;}}else m(a, 11 | j)}finally{d&&d(a,j)}},k=function(){c(a,j);d&&d(a,j)};i=function(){h=new e.Image;i=b;h.crossOrigin="Anonymous";h.onload=g;h.onerror=k;h.src=a};h.onload=g;h.onerror=k;h.src=a},w=function(a){try{if(!B&&g.userAgent.toLowerCase().indexOf("firefox")<0)return s.createObjectURL(new e.Blob([a],{type:"image/svg+xml;charset-utf-16"}))}catch(b){}return"data:image/svg+xml;charset=UTF-8,"+encodeURIComponent(a)},r=function(a,c){var f=l.createElement("a"),d=(b.filename||"chart")+"."+c,m;if(g.msSaveOrOpenBlob)g.msSaveOrOpenBlob(a, 12 | d);else if(f.download!==void 0)f.href=a,f.download=d,f.target="_blank",l.body.appendChild(f),f.click(),l.body.removeChild(f);else try{if(m=e.open(a,"chart"),m===void 0||m===null)throw"Failed to open window";}catch(i){e.location.href=a}},x=function(){var a,j,f=i.sanitizeSVG(p.innerHTML);if(b&&b.type==="image/svg+xml")try{g.msSaveOrOpenBlob?(j=new MSBlobBuilder,j.append(f),a=j.getBlob("image/svg+xml")):a=w(f),r(a,"svg")}catch(k){d()}else a=w(f),v(a,{},function(a){try{r(a,"png")}catch(b){d()}},function(){var a= 13 | l.createElement("canvas"),b=a.getContext("2d"),j=f.match(/^]*width\s*=\s*\"?(\d+)\"?[^>]*>/)[1]*n,h=f.match(/^]*height\s*=\s*\"?(\d+)\"?[^>]*>/)[1]*n,k=function(){b.drawSvg(f,0,0,j,h);try{r(g.msSaveOrOpenBlob?a.msToBlob():a.toDataURL("image/png"),"png")}catch(c){d()}};a.width=j;a.height=h;e.canvg?k():(i.showLoading(),y(c.getOptions().global.canvasToolsURL,function(){i.hideLoading();k()}))},d,d,function(){try{s.revokeObjectURL(a)}catch(b){}})},C=function(a,b){++t;b.imageElement.setAttributeNS("http://www.w3.org/1999/xlink", 14 | "href",a);t===k.length&&x()};c.wrap(c.Chart.prototype,"getChartHTML",function(a){p=this.container.cloneNode(!0);return a.apply(this,Array.prototype.slice.call(arguments,1))});i.getSVGForExport(b,A);k=p.getElementsByTagName("image");try{k.length||x();for(o=0,u=k.length;o所有监控的主机 5 |
6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% for host in host_list %} 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {% endfor %} 31 | ddddd 32 | 33 |
#HostnameIp AddrStatusDurationServicesLast Update
{{ host.id }} {{ host.name }} {{ host.ip_addr }}{{ host.get_status_display }}loading...Total(10),OK(3),Critical(4)
34 |
35 |
36 | 37 | {% endblock %} 38 | 39 | {% block bottom-js %} 40 | 85 | {% endblock %} -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/candlestick-and-volume/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
108 | 109 | 110 | -------------------------------------------------------------------------------- /templates/monitor/host_groups.html: -------------------------------------------------------------------------------- 1 | {% extends 'monitor/index.html' %} 2 | 3 | {% block page-title %} 4 | 5 | 主机组 6 | {% endblock %} 7 | 8 | {% block breadcrumb%} 9 | 13 | {% endblock %} 14 | 15 | {% block page-content %} 16 | 17 |
18 | {% for group in host_groups %} 19 |
20 | 21 | 22 | 23 |
24 |
25 |
26 | 27 |
28 | 29 | 36 |
37 |
38 |

{{ group.name }}

39 |
40 | 41 | 42 | 43 | 44 |
45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |
主机数服务数已触发事件DiasterHighAverageWarningInfo最后更新
{{ group.host_set.all.count }}
66 |
67 | 68 |
69 | 70 | 71 |
72 | 73 | 74 | 75 |
76 | 77 | {% endfor %} 78 |
79 | 80 | {% endblock %} 81 | 82 | {% block bottom-js %} 83 | 103 | {% endblock %} -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/flags-shapes/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 97 | 98 | 99 | 100 | 101 | 102 | 103 |
104 | 105 | 106 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/modules/no-data-to-display.src.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Highstock JS v4.2.4 (2016-04-14) 3 | * Plugin for displaying a message when there is no data visible in chart. 4 | * 5 | * (c) 2010-2016 Highsoft AS 6 | * Author: Oystein Moseng 7 | * 8 | * License: www.highcharts.com/license 9 | */ 10 | 11 | (function (factory) { 12 | if (typeof module === 'object' && module.exports) { 13 | module.exports = factory; 14 | } else { 15 | factory(Highcharts); 16 | } 17 | }(function (H) { 18 | 19 | var seriesTypes = H.seriesTypes, 20 | chartPrototype = H.Chart.prototype, 21 | defaultOptions = H.getOptions(), 22 | extend = H.extend, 23 | each = H.each; 24 | 25 | // Add language option 26 | extend(defaultOptions.lang, { 27 | noData: 'No data to display' 28 | }); 29 | 30 | // Add default display options for message 31 | defaultOptions.noData = { 32 | position: { 33 | x: 0, 34 | y: 0, 35 | align: 'center', 36 | verticalAlign: 'middle' 37 | }, 38 | attr: { 39 | }, 40 | style: { 41 | fontWeight: 'bold', 42 | fontSize: '12px', 43 | color: '#60606a' 44 | } 45 | // useHTML: false 46 | }; 47 | 48 | /** 49 | * Define hasData functions for series. These return true if there are data points on this series within the plot area 50 | */ 51 | function hasDataPie() { 52 | return !!this.points.length; /* != 0 */ 53 | } 54 | 55 | each(['pie', 'gauge', 'waterfall', 'bubble', 'treemap'], function (type) { 56 | if (seriesTypes[type]) { 57 | seriesTypes[type].prototype.hasData = hasDataPie; 58 | } 59 | }); 60 | 61 | H.Series.prototype.hasData = function () { 62 | return this.visible && this.dataMax !== undefined && this.dataMin !== undefined; // #3703 63 | }; 64 | 65 | /** 66 | * Display a no-data message. 67 | * 68 | * @param {String} str An optional message to show in place of the default one 69 | */ 70 | chartPrototype.showNoData = function (str) { 71 | var chart = this, 72 | options = chart.options, 73 | text = str || options.lang.noData, 74 | noDataOptions = options.noData; 75 | 76 | if (!chart.noDataLabel) { 77 | chart.noDataLabel = chart.renderer 78 | .label( 79 | text, 80 | 0, 81 | 0, 82 | null, 83 | null, 84 | null, 85 | noDataOptions.useHTML, 86 | null, 87 | 'no-data' 88 | ) 89 | .attr(noDataOptions.attr) 90 | .css(noDataOptions.style) 91 | .add(); 92 | chart.noDataLabel.align(extend(chart.noDataLabel.getBBox(), noDataOptions.position), false, 'plotBox'); 93 | } 94 | }; 95 | 96 | /** 97 | * Hide no-data message 98 | */ 99 | chartPrototype.hideNoData = function () { 100 | var chart = this; 101 | if (chart.noDataLabel) { 102 | chart.noDataLabel = chart.noDataLabel.destroy(); 103 | } 104 | }; 105 | 106 | /** 107 | * Returns true if there are data points within the plot area now 108 | */ 109 | chartPrototype.hasData = function () { 110 | var chart = this, 111 | series = chart.series, 112 | i = series.length; 113 | 114 | while (i--) { 115 | if (series[i].hasData() && !series[i].options.isInternal) { 116 | return true; 117 | } 118 | } 119 | 120 | return false; 121 | }; 122 | 123 | /** 124 | * Show no-data message if there is no data in sight. Otherwise, hide it. 125 | */ 126 | function handleNoData() { 127 | var chart = this; 128 | if (chart.hasData()) { 129 | chart.hideNoData(); 130 | } else { 131 | chart.showNoData(); 132 | } 133 | } 134 | 135 | /** 136 | * Add event listener to handle automatic display of no-data message 137 | */ 138 | chartPrototype.callbacks.push(function (chart) { 139 | H.addEvent(chart, 'load', handleNoData); 140 | H.addEvent(chart, 'redraw', handleNoData); 141 | }); 142 | 143 | })); 144 | -------------------------------------------------------------------------------- /statics/plugins/highstock/examples/lazy-loading/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 11 | 108 | 109 | 110 | 111 | 112 | 113 |
114 | 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/themes/dark-unica.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Dark theme for Highcharts JS 3 | * @author Torstein Honsi 4 | */ 5 | 6 | // Load the fonts 7 | Highcharts.createElement('link', { 8 | href: '//fonts.googleapis.com/css?family=Unica+One', 9 | rel: 'stylesheet', 10 | type: 'text/css' 11 | }, null, document.getElementsByTagName('head')[0]); 12 | 13 | Highcharts.theme = { 14 | colors: ["#2b908f", "#90ee7e", "#f45b5b", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee", 15 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"], 16 | chart: { 17 | backgroundColor: { 18 | linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 }, 19 | stops: [ 20 | [0, '#2a2a2b'], 21 | [1, '#3e3e40'] 22 | ] 23 | }, 24 | style: { 25 | fontFamily: "'Unica One', sans-serif" 26 | }, 27 | plotBorderColor: '#606063' 28 | }, 29 | title: { 30 | style: { 31 | color: '#E0E0E3', 32 | textTransform: 'uppercase', 33 | fontSize: '20px' 34 | } 35 | }, 36 | subtitle: { 37 | style: { 38 | color: '#E0E0E3', 39 | textTransform: 'uppercase' 40 | } 41 | }, 42 | xAxis: { 43 | gridLineColor: '#707073', 44 | labels: { 45 | style: { 46 | color: '#E0E0E3' 47 | } 48 | }, 49 | lineColor: '#707073', 50 | minorGridLineColor: '#505053', 51 | tickColor: '#707073', 52 | title: { 53 | style: { 54 | color: '#A0A0A3' 55 | 56 | } 57 | } 58 | }, 59 | yAxis: { 60 | gridLineColor: '#707073', 61 | labels: { 62 | style: { 63 | color: '#E0E0E3' 64 | } 65 | }, 66 | lineColor: '#707073', 67 | minorGridLineColor: '#505053', 68 | tickColor: '#707073', 69 | tickWidth: 1, 70 | title: { 71 | style: { 72 | color: '#A0A0A3' 73 | } 74 | } 75 | }, 76 | tooltip: { 77 | backgroundColor: 'rgba(0, 0, 0, 0.85)', 78 | style: { 79 | color: '#F0F0F0' 80 | } 81 | }, 82 | plotOptions: { 83 | series: { 84 | dataLabels: { 85 | color: '#B0B0B3' 86 | }, 87 | marker: { 88 | lineColor: '#333' 89 | } 90 | }, 91 | boxplot: { 92 | fillColor: '#505053' 93 | }, 94 | candlestick: { 95 | lineColor: 'white' 96 | }, 97 | errorbar: { 98 | color: 'white' 99 | } 100 | }, 101 | legend: { 102 | itemStyle: { 103 | color: '#E0E0E3' 104 | }, 105 | itemHoverStyle: { 106 | color: '#FFF' 107 | }, 108 | itemHiddenStyle: { 109 | color: '#606063' 110 | } 111 | }, 112 | credits: { 113 | style: { 114 | color: '#666' 115 | } 116 | }, 117 | labels: { 118 | style: { 119 | color: '#707073' 120 | } 121 | }, 122 | 123 | drilldown: { 124 | activeAxisLabelStyle: { 125 | color: '#F0F0F3' 126 | }, 127 | activeDataLabelStyle: { 128 | color: '#F0F0F3' 129 | } 130 | }, 131 | 132 | navigation: { 133 | buttonOptions: { 134 | symbolStroke: '#DDDDDD', 135 | theme: { 136 | fill: '#505053' 137 | } 138 | } 139 | }, 140 | 141 | // scroll charts 142 | rangeSelector: { 143 | buttonTheme: { 144 | fill: '#505053', 145 | stroke: '#000000', 146 | style: { 147 | color: '#CCC' 148 | }, 149 | states: { 150 | hover: { 151 | fill: '#707073', 152 | stroke: '#000000', 153 | style: { 154 | color: 'white' 155 | } 156 | }, 157 | select: { 158 | fill: '#000003', 159 | stroke: '#000000', 160 | style: { 161 | color: 'white' 162 | } 163 | } 164 | } 165 | }, 166 | inputBoxBorderColor: '#505053', 167 | inputStyle: { 168 | backgroundColor: '#333', 169 | color: 'silver' 170 | }, 171 | labelStyle: { 172 | color: 'silver' 173 | } 174 | }, 175 | 176 | navigator: { 177 | handles: { 178 | backgroundColor: '#666', 179 | borderColor: '#AAA' 180 | }, 181 | outlineColor: '#CCC', 182 | maskFill: 'rgba(255,255,255,0.1)', 183 | series: { 184 | color: '#7798BF', 185 | lineColor: '#A6C7ED' 186 | }, 187 | xAxis: { 188 | gridLineColor: '#505053' 189 | } 190 | }, 191 | 192 | scrollbar: { 193 | barBackgroundColor: '#808083', 194 | barBorderColor: '#808083', 195 | buttonArrowColor: '#CCC', 196 | buttonBackgroundColor: '#606063', 197 | buttonBorderColor: '#606063', 198 | rifleColor: '#FFF', 199 | trackBackgroundColor: '#404043', 200 | trackBorderColor: '#404043' 201 | }, 202 | 203 | // special colors for some of the 204 | legendBackgroundColor: 'rgba(0, 0, 0, 0.5)', 205 | background2: '#505053', 206 | dataLabelsColor: '#B0B0B3', 207 | textColor: '#C0C0C0', 208 | contrastTextColor: '#F0F0F3', 209 | maskColor: 'rgba(255,255,255,0.3)' 210 | }; 211 | 212 | // Apply the theme 213 | Highcharts.setOptions(Highcharts.theme); 214 | -------------------------------------------------------------------------------- /CrazyMonitorClient/plugins/windows/sysinfo.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | 4 | 5 | import platform 6 | import win32com 7 | import wmi 8 | import os 9 | 10 | 11 | def collect(): 12 | data = { 13 | 'os_type': platform.system(), 14 | 'os_release':"%s %s %s "%( platform.release() ,platform.architecture()[0],platform.version()), 15 | 'os_distribution': 'Microsoft', 16 | 'asset_type':'server' 17 | } 18 | #data.update(cpuinfo()) 19 | win32obj = Win32Info() 20 | data.update(win32obj.get_cpu_info()) 21 | data.update(win32obj.get_ram_info()) 22 | data.update(win32obj.get_server_info()) 23 | data.update(win32obj.get_disk_info()) 24 | data.update(win32obj.get_nic_info()) 25 | 26 | #for k,v in data.items(): 27 | # print k,v 28 | return data 29 | class Win32Info(object): 30 | def __init__(self): 31 | self.wmi_obj = wmi.WMI() 32 | self.wmi_service_obj = win32com.client.Dispatch("WbemScripting.SWbemLocator") 33 | self.wmi_service_connector =self.wmi_service_obj.ConnectServer(".","root\cimv2") 34 | 35 | def get_cpu_info(self): 36 | data = {} 37 | cpu_lists = self.wmi_obj.Win32_Processor() 38 | cpu_core_count = 0 39 | 40 | for cpu in cpu_lists: 41 | cpu_core_count += cpu.NumberOfCores 42 | cpu_model = cpu.Name 43 | data["cpu_count"] = len(cpu_lists) 44 | data["cpu_model"] = cpu_model 45 | data["cpu_core_count"] =cpu_core_count 46 | return data 47 | 48 | def get_ram_info(self): 49 | data = [] 50 | ram_collections = self.wmi_service_connector.ExecQuery("Select * from Win32_PhysicalMemory") 51 | for item in ram_collections: 52 | item_data = {} 53 | #print item 54 | mb = int(1024 * 1024) 55 | ram_size = int(item.Capacity) / mb 56 | item_data = { 57 | "slot":item.DeviceLocator.strip(), 58 | "capacity":ram_size, 59 | "model":item.Caption, 60 | "manufactory":item.Manufacturer, 61 | "sn":item.SerialNumber, 62 | } 63 | data.append(item_data) 64 | #for i in data: 65 | # print i 66 | return {"ram":data} 67 | def get_server_info(self): 68 | computer_info = self.wmi_obj.Win32_ComputerSystem()[0] 69 | system_info = self.wmi_obj.Win32_OperatingSystem()[0] 70 | data = {} 71 | data['manufactory'] = computer_info.Manufacturer 72 | data['model'] = computer_info.Model 73 | data['wake_up_type'] = computer_info.WakeUpType 74 | data['sn'] = system_info.SerialNumber 75 | #print data 76 | return data 77 | 78 | def get_disk_info(self): 79 | data = [] 80 | for disk in self.wmi_obj.Win32_DiskDrive(): 81 | #print disk.Model,disk.Size,disk.DeviceID,disk.Name,disk.Index,disk.SerialNumber,disk.SystemName,disk.Description 82 | item_data = {} 83 | iface_choices = ["SAS","SCSI","SATA","SSD"] 84 | for iface in iface_choices: 85 | if iface in disk.Model: 86 | item_data['iface_type'] = iface 87 | break 88 | else: 89 | item_data['iface_type'] = 'unknown' 90 | item_data['slot'] = disk.Index 91 | item_data['sn'] = disk.SerialNumber 92 | item_data['model'] = disk.Model 93 | item_data['manufactory'] = disk.Manufacturer 94 | item_data['capacity'] = int(disk.Size ) / (1024*1024*1024) 95 | data.append(item_data) 96 | return {'physical_disk_driver':data} 97 | def get_nic_info(self): 98 | data = [] 99 | for nic in self.wmi_obj.Win32_NetworkAdapterConfiguration(): 100 | if nic.MACAddress is not None: 101 | item_data = {} 102 | item_data['macaddress'] = nic.MACAddress 103 | item_data['model'] = nic.Caption 104 | item_data['name'] = nic.Index 105 | if nic.IPAddress is not None: 106 | item_data['ipaddress'] = nic.IPAddress[0] 107 | item_data['netmask'] = nic.IPSubnet 108 | else: 109 | item_data['ipaddress'] = '' 110 | item_data['netmask'] = '' 111 | bonding = 0 112 | #print nic.MACAddress ,nic.IPAddress,nic.ServiceName,nic.Caption,nic.IPSubnet 113 | #print item_data 114 | data.append(item_data) 115 | return {'nic':data} 116 | if __name__=="__main__": 117 | collect() -------------------------------------------------------------------------------- /CrazyMonitor/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for CrazyMonitor project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.9.1. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.9/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.9/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 's*t-3m!h%rh_vhcown4_eij(khv#^dt^esa-k6li4^-%!mtos$' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'monitor' 41 | ] 42 | 43 | MIDDLEWARE_CLASSES = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 50 | 'django.contrib.messages.middleware.MessageMiddleware', 51 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 52 | ] 53 | 54 | ROOT_URLCONF = 'CrazyMonitor.urls' 55 | 56 | TEMPLATES = [ 57 | { 58 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 59 | 'DIRS': [os.path.join(BASE_DIR, 'templates')] 60 | , 61 | 'APP_DIRS': True, 62 | 'OPTIONS': { 63 | 'context_processors': [ 64 | 'django.template.context_processors.debug', 65 | 'django.template.context_processors.request', 66 | 'django.contrib.auth.context_processors.auth', 67 | 'django.contrib.messages.context_processors.messages', 68 | ], 69 | }, 70 | }, 71 | ] 72 | 73 | WSGI_APPLICATION = 'CrazyMonitor.wsgi.application' 74 | 75 | 76 | # Database 77 | # https://docs.djangoproject.com/en/1.9/ref/settings/#databases 78 | 79 | 80 | DATABASES = { 81 | 'default': { 82 | 'ENGINE': 'django.db.backends.sqlite3', 83 | 'NAME': os.path.join(BASE_DIR, 'monitor_db.sqlite3'), 84 | } 85 | } 86 | 87 | 88 | # DATABASES = { 89 | # 'default': { 90 | # 'ENGINE': 'django.db.backends.mysql', 91 | # 'NAME': 'CrazyMonitor_test', 92 | # 'USER':'root', 93 | # 'PASSWORD':'', 94 | # 'HOST':'', 95 | # 'PORT':3306, 96 | # } 97 | # } 98 | 99 | 100 | 101 | # Password validation 102 | # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators 103 | 104 | AUTH_PASSWORD_VALIDATORS = [ 105 | { 106 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 107 | }, 108 | { 109 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 110 | }, 111 | { 112 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 113 | }, 114 | { 115 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 116 | }, 117 | ] 118 | 119 | 120 | # Internationalization 121 | # https://docs.djangoproject.com/en/1.9/topics/i18n/ 122 | 123 | LANGUAGE_CODE = 'en-us' 124 | 125 | TIME_ZONE = 'Asia/Shanghai' 126 | 127 | USE_I18N = True 128 | 129 | USE_L10N = True 130 | 131 | USE_TZ = True 132 | 133 | 134 | # Static files (CSS, JavaScript, Images) 135 | # https://docs.djangoproject.com/en/1.9/howto/static-files/ 136 | 137 | STATIC_URL = '/static/' 138 | STATICFILES_DIRS = ( 139 | "%s/%s" %(BASE_DIR, "statics"), 140 | ) 141 | 142 | 143 | AUTH_USER_MODEL = 'monitor.UserProfile' 144 | 145 | REDIS_CONN = { 146 | 'HOST': 'localhost', 147 | 'PORT': 6379, 148 | 'PASSWD':'' 149 | } 150 | 151 | #all the triggers will be published to this channel 152 | TRIGGER_CHAN = 'trigger_event_channel' 153 | #all latest monitor data will save under this key in redis 154 | 155 | STATUS_DATA_OPTIMIZATION = { 156 | 'latest':[0,600], #0 存储真实数据,600个点 157 | '10mins':[600,600], #4days, 每600s进行一次优化,存最大600个点 158 | '30mins':[1800,600],#14days 159 | '60mins':[3600,600], #25days 160 | } 161 | 162 | REPORT_LATE_TOLERANCE_TIME = 10 #allow service report late than monitor interval no more than defined seconds. 163 | 164 | 165 | 166 | EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' 167 | 168 | EMAIL_USE_TLS = False 169 | EMAIL_HOST = 'smtp.exmail.qq.com' 170 | EMAIL_PORT = 25 171 | EMAIL_HOST_USER = 'qiaojianlong@oldboyedu.com' 172 | EMAIL_HOST_PASSWORD = 'QJL171012qjl' 173 | DEFAULT_FROM_EMAIL = '老男孩IT教育' -------------------------------------------------------------------------------- /monitor/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from django import forms 4 | from monitor import models 5 | # Register your models here. 6 | 7 | from django.contrib.auth.admin import UserAdmin 8 | from django.contrib.auth.forms import ReadOnlyPasswordHashField 9 | 10 | class UserCreationForm(forms.ModelForm): 11 | """A form for creating new users. Includes all the required 12 | fields, plus a repeated password.""" 13 | password1 = forms.CharField(label='Password', widget=forms.PasswordInput) 14 | password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput) 15 | 16 | class Meta: 17 | model = models.UserProfile 18 | fields = ('email','name') 19 | 20 | def clean_password2(self): 21 | # Check that the two password entries match 22 | password1 = self.cleaned_data.get("password1") 23 | password2 = self.cleaned_data.get("password2") 24 | if password1 and password2 and password1 != password2: 25 | raise forms.ValidationError("Passwords don't match") 26 | return password2 27 | 28 | def save(self, commit=True): 29 | # Save the provided password in hashed format 30 | user = super(UserCreationForm, self).save(commit=False) 31 | user.set_password(self.cleaned_data["password1"]) 32 | if commit: 33 | user.save() 34 | return user 35 | 36 | 37 | class UserChangeForm(forms.ModelForm): 38 | """A form for updating users. Includes all the fields on 39 | the user, but replaces the password field with admin's 40 | password hash display field. 41 | """ 42 | password = ReadOnlyPasswordHashField(label="Password", 43 | help_text=("Raw passwords are not stored, so there is no way to see " 44 | "this user's password, but you can change the password " 45 | "using this form.")) 46 | 47 | class Meta: 48 | model = models.UserProfile 49 | fields = ('email','password','is_active', 'is_admin') 50 | 51 | def clean_password(self): 52 | # Regardless of what the user provides, return the initial value. 53 | # This is done here, rather than on the field, because the 54 | # field does not have access to the initial value 55 | return self.initial["password"] 56 | 57 | 58 | class UserProfileAdmin(UserAdmin): 59 | # The forms to add and change user instances 60 | form = UserChangeForm 61 | add_form = UserCreationForm 62 | 63 | # The fields to be used in displaying the User model. 64 | # These override the definitions on the base UserAdmin 65 | # that reference specific fields on auth.User. 66 | list_display = ('id','email','is_admin','is_active') 67 | list_filter = ('is_admin',) 68 | list_editable = ['is_admin'] 69 | 70 | fieldsets = ( 71 | (None, {'fields': ('email','name', 'password')}), 72 | ('Personal info', {'fields': ('phone','weixin','memo',)}), 73 | 74 | ('用户权限', {'fields': ('is_active','is_staff','is_admin','user_permissions','groups')}), 75 | 76 | ) 77 | # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin 78 | # overrides get_fieldsets to use this attribute when creating a user. 79 | add_fieldsets = ( 80 | (None, { 81 | 'classes': ('wide',), 82 | 'fields': ('email', 'password1', 'password2','is_active','is_admin')} 83 | ), 84 | ) 85 | search_fields = ('email',) 86 | ordering = ('email',) 87 | filter_horizontal = ('user_permissions','groups') 88 | 89 | 90 | 91 | 92 | 93 | 94 | class HostAdmin(admin.ModelAdmin): 95 | list_display = ('id','name','ip_addr','status') 96 | filter_horizontal = ('host_groups','templates') 97 | 98 | 99 | class TemplateAdmin(admin.ModelAdmin): 100 | filter_horizontal = ('services','triggers') 101 | 102 | class ServiceAdmin(admin.ModelAdmin): 103 | filter_horizontal = ('items',) 104 | list_display = ('name','interval','plugin_name') 105 | #list_select_related = ('items',) 106 | 107 | 108 | class TriggerExpressionInline(admin.TabularInline): 109 | model = models.TriggerExpression 110 | #exclude = ('memo',) 111 | #readonly_fields = ['create_date'] 112 | 113 | 114 | class TriggerAdmin(admin.ModelAdmin): 115 | list_display = ('name','severity','enabled') 116 | inlines = [TriggerExpressionInline,] 117 | #filter_horizontal = ('expressions',) 118 | 119 | 120 | class TriggerExpressionAdmin(admin.ModelAdmin): 121 | list_display = ('trigger','service','service_index','specified_index_key','operator_type','data_calc_func','threshold','logic_type') 122 | 123 | 124 | 125 | admin.site.register(models.Host,HostAdmin) 126 | admin.site.register(models.HostGroup) 127 | admin.site.register(models.Template,TemplateAdmin) 128 | admin.site.register(models.Service,ServiceAdmin) 129 | admin.site.register(models.Trigger,TriggerAdmin) 130 | admin.site.register(models.TriggerExpression,TriggerExpressionAdmin) 131 | admin.site.register(models.ServiceIndex) 132 | admin.site.register(models.Action) 133 | admin.site.register(models.ActionOperation) 134 | #admin.site.register(models.ActionCondtion,ActionConditionAdmin) 135 | admin.site.register(models.Maintenance) 136 | admin.site.register(models.UserProfile,UserProfileAdmin) 137 | admin.site.register(models.EventLog) -------------------------------------------------------------------------------- /templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | CrazyMonitor 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 59 | 60 |
61 |
62 | 82 |
83 | {% block right-panel-content %} 84 | {% endblock %} 85 |
86 |
87 |
88 | 89 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | {% block bottom-js %} 101 | 102 | {% endblock %} 103 | 104 | -------------------------------------------------------------------------------- /CrazyMonitorClient/core/client.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | 4 | import time 5 | from conf import settings 6 | import urllib 7 | import urllib2 8 | import json 9 | import threading 10 | from plugins import plugin_api 11 | 12 | class ClientHandle(object): 13 | def __init__(self): 14 | self.monitored_services = {} 15 | 16 | def load_latest_configs(self): 17 | ''' 18 | load the latest monitor configs from monitor server 19 | :return: 20 | ''' 21 | request_type = settings.configs['urls']['get_configs'][1] 22 | url = "%s/%s" %(settings.configs['urls']['get_configs'][0], settings.configs['HostID']) 23 | latest_configs = self.url_request(request_type,url) 24 | latest_configs = json.loads(latest_configs) 25 | self.monitored_services.update(latest_configs) 26 | 27 | def forever_run(self): 28 | ''' 29 | start the client program forever 30 | :return: 31 | ''' 32 | exit_flag = False 33 | config_last_update_time = 0 34 | while not exit_flag: 35 | if time.time() - config_last_update_time > settings.configs['ConfigUpdateInterval']: 36 | self.load_latest_configs() 37 | print("Loaded latest config:", self.monitored_services) 38 | config_last_update_time = time.time() 39 | #start to monitor services 40 | 41 | for service_name,val in self.monitored_services['services'].items(): 42 | if len(val) == 2:# means it's the first time to monitor 43 | self.monitored_services['services'][service_name].append(0) 44 | monitor_interval = val[1] 45 | last_invoke_time = val[2] 46 | if time.time() - last_invoke_time > monitor_interval: #needs to run the plugin 47 | print(last_invoke_time,time.time()) 48 | self.monitored_services['services'][service_name][2]= time.time() 49 | #start a new thread to call each monitor plugin 50 | t = threading.Thread(target=self.invoke_plugin,args=(service_name,val)) 51 | t.start() 52 | print("Going to monitor [%s]" % service_name) 53 | 54 | else: 55 | print("Going to monitor [%s] in [%s] secs" % (service_name, 56 | monitor_interval - (time.time()-last_invoke_time))) 57 | 58 | time.sleep(1) 59 | def invoke_plugin(self,service_name,val): 60 | ''' 61 | invoke the monitor plugin here, and send the data to monitor server after plugin returned status data each time 62 | :param val: [pulgin_name,monitor_interval,last_run_time] 63 | :return: 64 | ''' 65 | plugin_name = val[0] 66 | if hasattr(plugin_api,plugin_name): 67 | func = getattr(plugin_api,plugin_name) 68 | plugin_callback = func() 69 | #print("--monitor result:",plugin_callback) 70 | 71 | report_data = { 72 | 'client_id':settings.configs['HostID'], 73 | 'service_name':service_name, 74 | 'data':json.dumps(plugin_callback) 75 | } 76 | 77 | request_action = settings.configs['urls']['service_report'][1] 78 | request_url = settings.configs['urls']['service_report'][0] 79 | 80 | #report_data = json.dumps(report_data) 81 | print('---report data:',report_data) 82 | self.url_request(request_action,request_url,params=report_data) 83 | else: 84 | print("\033[31;1mCannot find service [%s]'s plugin name [%s] in plugin_api\033[0m"% (service_name,plugin_name )) 85 | print('--plugin:',val) 86 | 87 | 88 | def url_request(self,action,url,**extra_data): 89 | ''' 90 | cope with monitor server by url 91 | :param action: "get" or "post" 92 | :param url: witch url you want to request from the monitor server 93 | :param extra_data: extra parameters needed to be submited 94 | :return: 95 | ''' 96 | abs_url = "http://%s:%s/%s" % (settings.configs['Server'], 97 | settings.configs["ServerPort"], 98 | url) 99 | if action in ('get','GET'): 100 | print(abs_url,extra_data) 101 | try: 102 | req = urllib2.Request(abs_url) 103 | req_data = urllib2.urlopen(req,timeout=settings.configs['RequestTimeout']) 104 | callback = req_data.read() 105 | #print "-->server response:",callback 106 | return callback 107 | except urllib2.URLError as e: 108 | exit("\033[31;1m%s\033[0m"%e) 109 | 110 | elif action in ('post','POST'): 111 | #print(abs_url,extra_data['params']) 112 | try: 113 | data_encode = urllib.urlencode(extra_data['params']) 114 | req = urllib2.Request(url=abs_url,data=data_encode) 115 | res_data = urllib2.urlopen(req,timeout=settings.configs['RequestTimeout']) 116 | callback = res_data.read() 117 | callback = json.loads(callback) 118 | print "\033[31;1m[%s]:[%s]\033[0m response:\n%s" %(action,abs_url,callback) 119 | return callback 120 | except Exception as e: 121 | print('---exec',e) 122 | exit("\033[31;1m%s\033[0m"%e) 123 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/themes/dark-green.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Dark blue theme for Highcharts JS 3 | * @author Torstein Honsi 4 | */ 5 | 6 | Highcharts.theme = { 7 | colors: ["#DDDF0D", "#55BF3B", "#DF5353", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee", 8 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"], 9 | chart: { 10 | backgroundColor: { 11 | linearGradient: [0, 0, 250, 500], 12 | stops: [ 13 | [0, 'rgb(48, 96, 48)'], 14 | [1, 'rgb(0, 0, 0)'] 15 | ] 16 | }, 17 | borderColor: '#000000', 18 | borderWidth: 2, 19 | className: 'dark-container', 20 | plotBackgroundColor: 'rgba(255, 255, 255, .1)', 21 | plotBorderColor: '#CCCCCC', 22 | plotBorderWidth: 1 23 | }, 24 | title: { 25 | style: { 26 | color: '#C0C0C0', 27 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif' 28 | } 29 | }, 30 | subtitle: { 31 | style: { 32 | color: '#666666', 33 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif' 34 | } 35 | }, 36 | xAxis: { 37 | gridLineColor: '#333333', 38 | gridLineWidth: 1, 39 | labels: { 40 | style: { 41 | color: '#A0A0A0' 42 | } 43 | }, 44 | lineColor: '#A0A0A0', 45 | tickColor: '#A0A0A0', 46 | title: { 47 | style: { 48 | color: '#CCC', 49 | fontWeight: 'bold', 50 | fontSize: '12px', 51 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 52 | 53 | } 54 | } 55 | }, 56 | yAxis: { 57 | gridLineColor: '#333333', 58 | labels: { 59 | style: { 60 | color: '#A0A0A0' 61 | } 62 | }, 63 | lineColor: '#A0A0A0', 64 | minorTickInterval: null, 65 | tickColor: '#A0A0A0', 66 | tickWidth: 1, 67 | title: { 68 | style: { 69 | color: '#CCC', 70 | fontWeight: 'bold', 71 | fontSize: '12px', 72 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 73 | } 74 | } 75 | }, 76 | tooltip: { 77 | backgroundColor: 'rgba(0, 0, 0, 0.75)', 78 | style: { 79 | color: '#F0F0F0' 80 | } 81 | }, 82 | toolbar: { 83 | itemStyle: { 84 | color: 'silver' 85 | } 86 | }, 87 | plotOptions: { 88 | line: { 89 | dataLabels: { 90 | color: '#CCC' 91 | }, 92 | marker: { 93 | lineColor: '#333' 94 | } 95 | }, 96 | spline: { 97 | marker: { 98 | lineColor: '#333' 99 | } 100 | }, 101 | scatter: { 102 | marker: { 103 | lineColor: '#333' 104 | } 105 | }, 106 | candlestick: { 107 | lineColor: 'white' 108 | } 109 | }, 110 | legend: { 111 | itemStyle: { 112 | font: '9pt Trebuchet MS, Verdana, sans-serif', 113 | color: '#A0A0A0' 114 | }, 115 | itemHoverStyle: { 116 | color: '#FFF' 117 | }, 118 | itemHiddenStyle: { 119 | color: '#444' 120 | } 121 | }, 122 | credits: { 123 | style: { 124 | color: '#666' 125 | } 126 | }, 127 | labels: { 128 | style: { 129 | color: '#CCC' 130 | } 131 | }, 132 | 133 | 134 | navigation: { 135 | buttonOptions: { 136 | symbolStroke: '#DDDDDD', 137 | hoverSymbolStroke: '#FFFFFF', 138 | theme: { 139 | fill: { 140 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 141 | stops: [ 142 | [0.4, '#606060'], 143 | [0.6, '#333333'] 144 | ] 145 | }, 146 | stroke: '#000000' 147 | } 148 | } 149 | }, 150 | 151 | // scroll charts 152 | rangeSelector: { 153 | buttonTheme: { 154 | fill: { 155 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 156 | stops: [ 157 | [0.4, '#888'], 158 | [0.6, '#555'] 159 | ] 160 | }, 161 | stroke: '#000000', 162 | style: { 163 | color: '#CCC', 164 | fontWeight: 'bold' 165 | }, 166 | states: { 167 | hover: { 168 | fill: { 169 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 170 | stops: [ 171 | [0.4, '#BBB'], 172 | [0.6, '#888'] 173 | ] 174 | }, 175 | stroke: '#000000', 176 | style: { 177 | color: 'white' 178 | } 179 | }, 180 | select: { 181 | fill: { 182 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 183 | stops: [ 184 | [0.1, '#000'], 185 | [0.3, '#333'] 186 | ] 187 | }, 188 | stroke: '#000000', 189 | style: { 190 | color: 'yellow' 191 | } 192 | } 193 | } 194 | }, 195 | inputStyle: { 196 | backgroundColor: '#333', 197 | color: 'silver' 198 | }, 199 | labelStyle: { 200 | color: 'silver' 201 | } 202 | }, 203 | 204 | navigator: { 205 | handles: { 206 | backgroundColor: '#666', 207 | borderColor: '#AAA' 208 | }, 209 | outlineColor: '#CCC', 210 | maskFill: 'rgba(16, 16, 16, 0.5)', 211 | series: { 212 | color: '#7798BF', 213 | lineColor: '#A6C7ED' 214 | } 215 | }, 216 | 217 | scrollbar: { 218 | barBackgroundColor: { 219 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 220 | stops: [ 221 | [0.4, '#888'], 222 | [0.6, '#555'] 223 | ] 224 | }, 225 | barBorderColor: '#CCC', 226 | buttonArrowColor: '#CCC', 227 | buttonBackgroundColor: { 228 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 229 | stops: [ 230 | [0.4, '#888'], 231 | [0.6, '#555'] 232 | ] 233 | }, 234 | buttonBorderColor: '#CCC', 235 | rifleColor: '#FFF', 236 | trackBackgroundColor: { 237 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 238 | stops: [ 239 | [0, '#000'], 240 | [1, '#333'] 241 | ] 242 | }, 243 | trackBorderColor: '#666' 244 | }, 245 | 246 | // special colors for some of the 247 | legendBackgroundColor: 'rgba(0, 0, 0, 0.5)', 248 | background2: 'rgb(35, 35, 70)', 249 | dataLabelsColor: '#444', 250 | textColor: '#C0C0C0', 251 | maskColor: 'rgba(255,255,255,0.3)' 252 | }; 253 | 254 | // Apply the theme 255 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme); 256 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/themes/dark-blue.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Dark blue theme for Highcharts JS 3 | * @author Torstein Honsi 4 | */ 5 | 6 | Highcharts.theme = { 7 | colors: ["#DDDF0D", "#55BF3B", "#DF5353", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee", 8 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"], 9 | chart: { 10 | backgroundColor: { 11 | linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 }, 12 | stops: [ 13 | [0, 'rgb(48, 48, 96)'], 14 | [1, 'rgb(0, 0, 0)'] 15 | ] 16 | }, 17 | borderColor: '#000000', 18 | borderWidth: 2, 19 | className: 'dark-container', 20 | plotBackgroundColor: 'rgba(255, 255, 255, .1)', 21 | plotBorderColor: '#CCCCCC', 22 | plotBorderWidth: 1 23 | }, 24 | title: { 25 | style: { 26 | color: '#C0C0C0', 27 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif' 28 | } 29 | }, 30 | subtitle: { 31 | style: { 32 | color: '#666666', 33 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif' 34 | } 35 | }, 36 | xAxis: { 37 | gridLineColor: '#333333', 38 | gridLineWidth: 1, 39 | labels: { 40 | style: { 41 | color: '#A0A0A0' 42 | } 43 | }, 44 | lineColor: '#A0A0A0', 45 | tickColor: '#A0A0A0', 46 | title: { 47 | style: { 48 | color: '#CCC', 49 | fontWeight: 'bold', 50 | fontSize: '12px', 51 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 52 | 53 | } 54 | } 55 | }, 56 | yAxis: { 57 | gridLineColor: '#333333', 58 | labels: { 59 | style: { 60 | color: '#A0A0A0' 61 | } 62 | }, 63 | lineColor: '#A0A0A0', 64 | minorTickInterval: null, 65 | tickColor: '#A0A0A0', 66 | tickWidth: 1, 67 | title: { 68 | style: { 69 | color: '#CCC', 70 | fontWeight: 'bold', 71 | fontSize: '12px', 72 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 73 | } 74 | } 75 | }, 76 | tooltip: { 77 | backgroundColor: 'rgba(0, 0, 0, 0.75)', 78 | style: { 79 | color: '#F0F0F0' 80 | } 81 | }, 82 | toolbar: { 83 | itemStyle: { 84 | color: 'silver' 85 | } 86 | }, 87 | plotOptions: { 88 | line: { 89 | dataLabels: { 90 | color: '#CCC' 91 | }, 92 | marker: { 93 | lineColor: '#333' 94 | } 95 | }, 96 | spline: { 97 | marker: { 98 | lineColor: '#333' 99 | } 100 | }, 101 | scatter: { 102 | marker: { 103 | lineColor: '#333' 104 | } 105 | }, 106 | candlestick: { 107 | lineColor: 'white' 108 | } 109 | }, 110 | legend: { 111 | itemStyle: { 112 | font: '9pt Trebuchet MS, Verdana, sans-serif', 113 | color: '#A0A0A0' 114 | }, 115 | itemHoverStyle: { 116 | color: '#FFF' 117 | }, 118 | itemHiddenStyle: { 119 | color: '#444' 120 | } 121 | }, 122 | credits: { 123 | style: { 124 | color: '#666' 125 | } 126 | }, 127 | labels: { 128 | style: { 129 | color: '#CCC' 130 | } 131 | }, 132 | 133 | navigation: { 134 | buttonOptions: { 135 | symbolStroke: '#DDDDDD', 136 | hoverSymbolStroke: '#FFFFFF', 137 | theme: { 138 | fill: { 139 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 140 | stops: [ 141 | [0.4, '#606060'], 142 | [0.6, '#333333'] 143 | ] 144 | }, 145 | stroke: '#000000' 146 | } 147 | } 148 | }, 149 | 150 | // scroll charts 151 | rangeSelector: { 152 | buttonTheme: { 153 | fill: { 154 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 155 | stops: [ 156 | [0.4, '#888'], 157 | [0.6, '#555'] 158 | ] 159 | }, 160 | stroke: '#000000', 161 | style: { 162 | color: '#CCC', 163 | fontWeight: 'bold' 164 | }, 165 | states: { 166 | hover: { 167 | fill: { 168 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 169 | stops: [ 170 | [0.4, '#BBB'], 171 | [0.6, '#888'] 172 | ] 173 | }, 174 | stroke: '#000000', 175 | style: { 176 | color: 'white' 177 | } 178 | }, 179 | select: { 180 | fill: { 181 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 182 | stops: [ 183 | [0.1, '#000'], 184 | [0.3, '#333'] 185 | ] 186 | }, 187 | stroke: '#000000', 188 | style: { 189 | color: 'yellow' 190 | } 191 | } 192 | } 193 | }, 194 | inputStyle: { 195 | backgroundColor: '#333', 196 | color: 'silver' 197 | }, 198 | labelStyle: { 199 | color: 'silver' 200 | } 201 | }, 202 | 203 | navigator: { 204 | handles: { 205 | backgroundColor: '#666', 206 | borderColor: '#AAA' 207 | }, 208 | outlineColor: '#CCC', 209 | maskFill: 'rgba(16, 16, 16, 0.5)', 210 | series: { 211 | color: '#7798BF', 212 | lineColor: '#A6C7ED' 213 | } 214 | }, 215 | 216 | scrollbar: { 217 | barBackgroundColor: { 218 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 219 | stops: [ 220 | [0.4, '#888'], 221 | [0.6, '#555'] 222 | ] 223 | }, 224 | barBorderColor: '#CCC', 225 | buttonArrowColor: '#CCC', 226 | buttonBackgroundColor: { 227 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 228 | stops: [ 229 | [0.4, '#888'], 230 | [0.6, '#555'] 231 | ] 232 | }, 233 | buttonBorderColor: '#CCC', 234 | rifleColor: '#FFF', 235 | trackBackgroundColor: { 236 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 237 | stops: [ 238 | [0, '#000'], 239 | [1, '#333'] 240 | ] 241 | }, 242 | trackBorderColor: '#666' 243 | }, 244 | 245 | // special colors for some of the 246 | legendBackgroundColor: 'rgba(0, 0, 0, 0.5)', 247 | background2: 'rgb(35, 35, 70)', 248 | dataLabelsColor: '#444', 249 | textColor: '#C0C0C0', 250 | maskColor: 'rgba(255,255,255,0.3)' 251 | }; 252 | 253 | // Apply the theme 254 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme); 255 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/themes/gray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Gray theme for Highcharts JS 3 | * @author Torstein Honsi 4 | */ 5 | 6 | Highcharts.theme = { 7 | colors: ["#DDDF0D", "#7798BF", "#55BF3B", "#DF5353", "#aaeeee", "#ff0066", "#eeaaee", 8 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"], 9 | chart: { 10 | backgroundColor: { 11 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 12 | stops: [ 13 | [0, 'rgb(96, 96, 96)'], 14 | [1, 'rgb(16, 16, 16)'] 15 | ] 16 | }, 17 | borderWidth: 0, 18 | borderRadius: 0, 19 | plotBackgroundColor: null, 20 | plotShadow: false, 21 | plotBorderWidth: 0 22 | }, 23 | title: { 24 | style: { 25 | color: '#FFF', 26 | font: '16px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 27 | } 28 | }, 29 | subtitle: { 30 | style: { 31 | color: '#DDD', 32 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 33 | } 34 | }, 35 | xAxis: { 36 | gridLineWidth: 0, 37 | lineColor: '#999', 38 | tickColor: '#999', 39 | labels: { 40 | style: { 41 | color: '#999', 42 | fontWeight: 'bold' 43 | } 44 | }, 45 | title: { 46 | style: { 47 | color: '#AAA', 48 | font: 'bold 12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 49 | } 50 | } 51 | }, 52 | yAxis: { 53 | alternateGridColor: null, 54 | minorTickInterval: null, 55 | gridLineColor: 'rgba(255, 255, 255, .1)', 56 | minorGridLineColor: 'rgba(255,255,255,0.07)', 57 | lineWidth: 0, 58 | tickWidth: 0, 59 | labels: { 60 | style: { 61 | color: '#999', 62 | fontWeight: 'bold' 63 | } 64 | }, 65 | title: { 66 | style: { 67 | color: '#AAA', 68 | font: 'bold 12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 69 | } 70 | } 71 | }, 72 | legend: { 73 | itemStyle: { 74 | color: '#CCC' 75 | }, 76 | itemHoverStyle: { 77 | color: '#FFF' 78 | }, 79 | itemHiddenStyle: { 80 | color: '#333' 81 | } 82 | }, 83 | labels: { 84 | style: { 85 | color: '#CCC' 86 | } 87 | }, 88 | tooltip: { 89 | backgroundColor: { 90 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 91 | stops: [ 92 | [0, 'rgba(96, 96, 96, .8)'], 93 | [1, 'rgba(16, 16, 16, .8)'] 94 | ] 95 | }, 96 | borderWidth: 0, 97 | style: { 98 | color: '#FFF' 99 | } 100 | }, 101 | 102 | 103 | plotOptions: { 104 | series: { 105 | nullColor: '#444444' 106 | }, 107 | line: { 108 | dataLabels: { 109 | color: '#CCC' 110 | }, 111 | marker: { 112 | lineColor: '#333' 113 | } 114 | }, 115 | spline: { 116 | marker: { 117 | lineColor: '#333' 118 | } 119 | }, 120 | scatter: { 121 | marker: { 122 | lineColor: '#333' 123 | } 124 | }, 125 | candlestick: { 126 | lineColor: 'white' 127 | } 128 | }, 129 | 130 | toolbar: { 131 | itemStyle: { 132 | color: '#CCC' 133 | } 134 | }, 135 | 136 | navigation: { 137 | buttonOptions: { 138 | symbolStroke: '#DDDDDD', 139 | hoverSymbolStroke: '#FFFFFF', 140 | theme: { 141 | fill: { 142 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 143 | stops: [ 144 | [0.4, '#606060'], 145 | [0.6, '#333333'] 146 | ] 147 | }, 148 | stroke: '#000000' 149 | } 150 | } 151 | }, 152 | 153 | // scroll charts 154 | rangeSelector: { 155 | buttonTheme: { 156 | fill: { 157 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 158 | stops: [ 159 | [0.4, '#888'], 160 | [0.6, '#555'] 161 | ] 162 | }, 163 | stroke: '#000000', 164 | style: { 165 | color: '#CCC', 166 | fontWeight: 'bold' 167 | }, 168 | states: { 169 | hover: { 170 | fill: { 171 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 172 | stops: [ 173 | [0.4, '#BBB'], 174 | [0.6, '#888'] 175 | ] 176 | }, 177 | stroke: '#000000', 178 | style: { 179 | color: 'white' 180 | } 181 | }, 182 | select: { 183 | fill: { 184 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 185 | stops: [ 186 | [0.1, '#000'], 187 | [0.3, '#333'] 188 | ] 189 | }, 190 | stroke: '#000000', 191 | style: { 192 | color: 'yellow' 193 | } 194 | } 195 | } 196 | }, 197 | inputStyle: { 198 | backgroundColor: '#333', 199 | color: 'silver' 200 | }, 201 | labelStyle: { 202 | color: 'silver' 203 | } 204 | }, 205 | 206 | navigator: { 207 | handles: { 208 | backgroundColor: '#666', 209 | borderColor: '#AAA' 210 | }, 211 | outlineColor: '#CCC', 212 | maskFill: 'rgba(16, 16, 16, 0.5)', 213 | series: { 214 | color: '#7798BF', 215 | lineColor: '#A6C7ED' 216 | } 217 | }, 218 | 219 | scrollbar: { 220 | barBackgroundColor: { 221 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 222 | stops: [ 223 | [0.4, '#888'], 224 | [0.6, '#555'] 225 | ] 226 | }, 227 | barBorderColor: '#CCC', 228 | buttonArrowColor: '#CCC', 229 | buttonBackgroundColor: { 230 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 231 | stops: [ 232 | [0.4, '#888'], 233 | [0.6, '#555'] 234 | ] 235 | }, 236 | buttonBorderColor: '#CCC', 237 | rifleColor: '#FFF', 238 | trackBackgroundColor: { 239 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 240 | stops: [ 241 | [0, '#000'], 242 | [1, '#333'] 243 | ] 244 | }, 245 | trackBorderColor: '#666' 246 | }, 247 | 248 | // special colors for some of the demo examples 249 | legendBackgroundColor: 'rgba(48, 48, 48, 0.8)', 250 | background2: 'rgb(70, 70, 70)', 251 | dataLabelsColor: '#444', 252 | textColor: '#E0E0E0', 253 | maskColor: 'rgba(255,255,255,0.3)' 254 | }; 255 | 256 | // Apply the theme 257 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme); 258 | -------------------------------------------------------------------------------- /statics/plugins/highstock/js/modules/boost.js: -------------------------------------------------------------------------------- 1 | (function(c){typeof module==="object"&&module.exports?module.exports=c:c(Highcharts)})(function(c){function y(a,b,d,f,h){for(var h=h||0,f=f||z,c=h+f,n=!0;n&&h(b.boostThreshold||Number.MAX_VALUE)&&typeof f.min==="number"&&typeof f.max==="number"&&(!a||typeof d.min==="number"&&typeof d.max==="number")},destroyGraphics:function(){var a=this,b=this.points,d,f;if(b)for(f=0;f99999)d.options.loading=U(i,{labelStyle:{backgroundColor:"rgba(255,255,255,0.75)",padding:"1em",borderRadius:"0.5em"},style:{backgroundColor:"none",opacity:1}}),clearTimeout(A),d.showLoading("Drawing..."), 9 | d.options.loading=i;y(L?a.data:j||l,function(b,c){var e,g,j,i,l=typeof d.index==="undefined",n=!0;if(!l){N?(e=b[0],g=b[1]):(e=b,g=k[c]);if(K)N&&(g=b.slice(1,3)),i=g[0],g=g[1];else if(L)e=b.x,g=b.stackY,i=g-b.y;j=g===null;aa||(n=g>=t&&g<=W);if(!j&&e>=p&&e<=r&&n)if(e=Math.round(f.toPixels(e,!0)),X){if(o===void 0||e===u){K||(i=g);if(q===void 0||g>w)w=g,q=c;if(o===void 0||i",client_id) 95 | config_obj = ClientHandler(client_id) 96 | config = config_obj.fetch_configs() 97 | 98 | if config: 99 | return HttpResponse(json.dumps(config)) 100 | 101 | @csrf_exempt 102 | def service_data_report(request): 103 | if request.method == 'POST': 104 | print("---->",request.POST) 105 | #REDIS_OBJ.set("test_alex",'hahaha') 106 | try: 107 | print('host=%s, service=%s' %(request.POST.get('client_id'),request.POST.get('service_name') ) ) 108 | data = json.loads(request.POST['data']) 109 | #print(data) 110 | #StatusData_1_memory_latest 111 | client_id = request.POST.get('client_id') 112 | service_name = request.POST.get('service_name') 113 | #把数据存下来 114 | data_saveing_obj = data_optimization.DataStore(client_id,service_name,data,REDIS_OBJ) 115 | 116 | #redis_key_format = "StatusData_%s_%s_latest" %(client_id,service_name) 117 | #data['report_time'] = time.time() 118 | #REDIS_OBJ.lpush(redis_key_format,json.dumps(data)) 119 | 120 | #在这里同时触发监控(在这里触发的好处是什么呢?) 121 | host_obj = models.Host.objects.get(id=client_id) 122 | service_triggers = get_host_triggers(host_obj) 123 | 124 | trigger_handler = data_processing.DataHandler(settings,connect_redis=False) 125 | for trigger in service_triggers: 126 | trigger_handler.load_service_data_and_calulating(host_obj,trigger,REDIS_OBJ) 127 | print("service trigger::",service_triggers) 128 | 129 | 130 | #更新主机存活状态 131 | #host_alive_key = "HostAliveFlag_%s" % client_id 132 | #REDIS_OBJ.set(host_alive_key,time.time()) 133 | except IndexError as e: 134 | print('----->err:',e) 135 | 136 | 137 | return HttpResponse(json.dumps("---report success---")) 138 | 139 | 140 | def graphs_generator(request): 141 | 142 | graphs_generator = graphs.GraphGenerator2(request,REDIS_OBJ) 143 | graphs_data = graphs_generator.get_host_graph() 144 | print("graphs_data",graphs_data) 145 | return HttpResponse(json.dumps(graphs_data)) 146 | 147 | def graph_bak(request): 148 | 149 | 150 | #host_id = request.GET.get('host_id') 151 | #service_key = request.GET.get('service_key') 152 | 153 | #print("graph:", host_id,service_key) 154 | 155 | graph_generator = graphs.GraphGenerator(request,REDIS_OBJ) 156 | graph_data = graph_generator.get_graph_data() 157 | if graph_data: 158 | return HttpResponse(json.dumps(graph_data)) 159 | 160 | 161 | def trigger_list(request): 162 | 163 | host_id = request.GET.get("by_host_id") 164 | 165 | host_obj = models.Host.objects.get(id=host_id) 166 | 167 | alert_list = host_obj.eventlog_set.all().order_by('-date') 168 | return render(request,'monitor/trigger_list.html',locals()) 169 | 170 | 171 | def host_groups(request): 172 | 173 | host_groups = models.HostGroup.objects.all() 174 | return render(request,'monitor/host_groups.html',locals()) -------------------------------------------------------------------------------- /monitor/graphs.py: -------------------------------------------------------------------------------- 1 | #_*_coding:utf-8_*_ 2 | __author__ = 'Alex Li' 3 | 4 | from monitor import models 5 | import json 6 | from CrazyMonitor import settings 7 | 8 | class GraphGenerator2(object): 9 | ''' 10 | 产生流量图 11 | ''' 12 | def __init__(self,request,redis_obj): 13 | self.request = request 14 | self.redis = redis_obj 15 | self.host_id = self.request.GET.get('host_id') 16 | self.time_range = self.request.GET.get('time_range') 17 | 18 | def get_host_graph(self): 19 | ''' 20 | 生成此主机关联的所有图 21 | :return: 22 | ''' 23 | host_obj = models.Host.objects.get(id=self.host_id) 24 | service_data_dic = {} 25 | template_list = list(host_obj.templates.select_related()) 26 | for g in host_obj.host_groups.select_related(): 27 | template_list.extend(list(g.templates.select_related())) 28 | template_list = set(template_list) 29 | for template in template_list: 30 | for service in template.services.select_related(): 31 | service_data_dic[service.id] = { 32 | 'name':service.name, 33 | 'index_data':{}, 34 | 'has_sub_service': service.has_sub_service, 35 | 'raw_data':[], 36 | 'items': [item.key for item in service.items.select_related() ] 37 | } 38 | '''if not service.has_sub_service: 39 | for index in service.items.select_related(): 40 | service_data_dic[service.id]['index_data'][index.key] = { 41 | 'id': index.id, 42 | 'name':index.name, 43 | 'data':[] 44 | } 45 | #else: #like nic service 46 | ''' 47 | 48 | print(service_data_dic) 49 | #service_data_dic 50 | #开始取数据 51 | for service_id,val_dic in service_data_dic.items(): 52 | #if val_dic['has_sub_service'] == False: 53 | service_redis_key = "StatusData_%s_%s_%s" %(self.host_id,val_dic['name'],self.time_range) 54 | print('service_redis_key',service_redis_key) 55 | service_raw_data = self.redis.lrange(service_redis_key,0,-1) 56 | service_raw_data = [item.decode() for item in service_raw_data] 57 | service_data_dic[service_id]['raw_data'] = service_raw_data 58 | 59 | return service_data_dic 60 | 61 | class GraphGenerator(object): 62 | ''' 63 | generate graphs 64 | ''' 65 | 66 | def __init__(self,request,redis_obj): 67 | self.request = request 68 | self.host_id = self.request.GET.get('host_id') 69 | self.service_name = self.request.GET.get('service_key') 70 | self.index_key = self.request.GET.get('index_key') 71 | self.time_range = self.request.GET.get('time_range') 72 | self.sub_service_name = self.request.GET.get('sub_service_key') 73 | self.redis = redis_obj 74 | 75 | print("sub service key:", self.sub_service_name) 76 | 77 | def get_graph_data(self): 78 | #data_store_key = "StatusData_%s_%s_latest" %(self.host_id,self.service_name) 79 | data_store_key = "StatusData_%s_%s_%s" %(self.host_id,self.service_name,self.time_range) 80 | data_set = self.redis.lrange(data_store_key,0,-1) 81 | print("data store key:", data_store_key) 82 | print("data point nums:", len(data_set)) 83 | #print("data points:", data_set) 84 | service_obj = models.Service.objects.get(name=self.service_name) 85 | data_dic = {} #store graph data later 86 | for item in service_obj.items.select_related(): 87 | data_dic[item.key] = [] 88 | 89 | if data_set: #make sure data set not empty 90 | 91 | print("service data for graph:", data_dic) 92 | if self.sub_service_name == None or self.sub_service_name == 'undefined': 93 | for data_point in data_set: 94 | #data_point sample data:('-->', {u'status': 0, u'iowait': u'0.00', u'system': u'1.01', u'idle': u'96.98', u'user': u'2.01', u'steal': u'0.00', u'nice': u'0.00'}, 1461840915.038072) 95 | val,timestamp = json.loads(data_point) 96 | if val: 97 | for k,v in val.items(): 98 | if k in data_dic: 99 | '''if len(data_dic[k]) > 0: #不是第一次存值 100 | last_point_save_time = data_dic[k][-1][0] #microseconds 101 | data_point_interval =settings.STATUS_DATA_OPTIMIZATION[self.time_range][0] 102 | if timestamp*1000 - last_point_save_time > data_point_interval: 103 | #这里出现中断了 104 | data_dic[k].append([last_point_save_time + data_point_interval,0]) 105 | else:#没有中断过,什么都 不用做哈哈 106 | pass 107 | ''' 108 | if type(v) is not list: 109 | data_dic[k].append([timestamp*1000,float(v)]) 110 | else: #v = [avg,max,min,mid] 111 | data_dic[k].append([timestamp*1000,float(v[0])]) #暂时只往前台 返回 average数据 112 | else: #has sub service 113 | print("\033[44;1m------------subservice key: %s, %s\033[0m" %(self.sub_service_name,self.service_name)) 114 | for data_point in data_set: 115 | #data_point sample data:('-->', {u'status': 0, u'iowait': u'0.00', u'system': u'1.01', u'idle': u'96.98', u'user': u'2.01', u'steal': u'0.00', u'nice': u'0.00'}, 1461840915.038072) 116 | val,timestamp = json.loads(data_point) 117 | if val: 118 | if val.get('data'): 119 | for sub_service_key,v_dic in val['data'].items(): 120 | for k,v in v_dic.items(): 121 | if k in data_dic: 122 | if type(v) is not list: 123 | data_dic[k].append([timestamp*1000,float(v)]) 124 | else: #v = [avg,max,min,mid] 125 | data_dic[k].append([timestamp*1000,float(v[0])]) #暂时只往前台 返回 average数据 126 | 127 | for k,v in data_dic.items(): 128 | print(k,v) 129 | 130 | return data_dic --------------------------------------------------------------------------------