├── .gitignore
├── .npmignore
├── .travis.yml
├── LICENSE
├── README.md
├── README_zh.md
├── assets
├── dist
│ ├── build.js
│ └── build.js.map
├── index.html
├── memeye-logo.png
└── memeye.ico
├── client
├── .babelrc
├── .gitignore
├── README.md
├── index.html
├── package.json
├── src
│ ├── App.vue
│ ├── assets
│ │ ├── logo.png
│ │ └── memeye.ico
│ ├── components
│ │ ├── Memeye.vue
│ │ ├── Panel.vue
│ │ ├── PanelItem.vue
│ │ └── charts
│ │ │ ├── OSCPUSUsedLine.js
│ │ │ ├── OSMemoryLine.js
│ │ │ ├── OSMemoryPie.js
│ │ │ ├── ProcessDoughnut.js
│ │ │ ├── ProcessLine.js
│ │ │ ├── V8HeapSpaceBar.js
│ │ │ └── V8HeapSpacePie.js
│ └── main.js
├── webpack.config.js
└── yarn.lock
├── coverage
├── coverage.json
├── lcov-report
│ ├── base.css
│ ├── index.html
│ ├── lib
│ │ └── index.html
│ ├── prettify.css
│ ├── prettify.js
│ ├── sort-arrow-sprite.png
│ └── sorter.js
└── lcov.info
├── example
└── small-example.js
├── index.js
├── package.json
├── src
├── dashboard
│ ├── index.js
│ └── server.js
├── index.js
└── lib
│ ├── Collector.js
│ ├── Indicators.js
│ └── Logger.js
├── test
├── bootstarp.js
└── unit
│ ├── Collector.test.js
│ └── Indicators.test.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | coverage
4 | npm-debug.log
5 | yarn-error.log
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .gitignore
3 | .travis.yml
4 | client
5 | coverage
6 | example
7 | test
8 | node_modules
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "node"
4 | - "6"
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016-2017 JC-Huang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | [](https://travis-ci.org/JerryC8080/Memeye)
7 | [](https://badge.fury.io/js/memeye)
8 | [](http://packagequality.com/#?package=memeye)
9 | [](https://www.npmjs.com/package/memeye)
10 | [](https://github.com/JerryC8080/Memeye/blob/master/LICENSE)
11 |
12 | # Memeye
13 | [中文版](README_zh.md)
14 |
15 | # Introduction
16 |
17 | Memeye is a lightweight NodeJS process monitoring tool that provides data visualization of process memory, V8 heap space memory, and operating system memory.
18 | The front part, with [Vue2](https://github.com/vuejs/vue) and [ChartJS](https://github.com/chartjs/Chart.js), provides a nice dynamic dashboard.
19 | Memeye in the host process, only the implantation of a simple data collector, the other work is to start a child-process, by the child-process to carry out.
20 | This will minimize the impact of Memeye's code on the host process to ensure the authenticity of the data.
21 |
22 | ### Feature
23 | - Lightweight
24 | - Simple
25 | - For development
26 | - Visualization
27 |
28 |
29 | *Note: Memeye only support a single process, NodeJS distributed process is not applicable, it is not recommended in the product environment。*
30 |
31 | # Motivation
32 | As we all know, NodeJS is very sensitive to memory.
33 | In April last year I used NodeJS to build a marketing project, on the day of project online PV broke one million.
34 | Which is showing a continuous upward trend in memory, in the process of troubleshooting problems, i want to find a lightweight, as long as the visual display of the use of memory tools, but no result.
35 | Then there is the idea of this project, but at that time because of the busy only made a simple Demo to use (Memeye v0.0.3).
36 | Recently there is time, once again turned out to reorganize and revision, add more type of the data display.
37 |
38 |
39 | # Demo
40 | [See preview demo](http://jerryc8080.github.io/Memeye/)
41 |
42 | # Compatibility
43 | - Node v7.x
44 | - Node v6.x
45 |
46 | # Install & Usage
47 |
48 | For install simply run :
49 |
50 | ```
51 | npm install memeye --save-dev
52 | ```
53 |
54 | Then require it in your nodejs application
55 |
56 | ```
57 | const memeye = require('memeye');
58 | memeye();
59 | ```
60 |
61 | Then open your browser and load address:
62 |
63 | ```
64 | http://localhost:23333 //23333 port by default.
65 | ```
66 |
67 | That's it! No more options, no more config, just so easy.
68 |
69 | # How it works
70 |
71 | Memeye has three core concept: Collector, Indicator and Dashboard.
72 | While Collector runing in your nodejs process, Indicators and Dashboard runing on the child-process, in this way Memeye will make as little influence as possible to your nodejs process.
73 |
74 | ## Collector
75 | Collector will wathching and collecting data from the host node process、v8 heap and operrating system ,then send the datas to dashboard process with IPC communication channel.
76 |
77 | ## Indicator
78 | Indicator like a state machine . When attribute changed, the instance of Indicator will emit an event. So we can use it to handle our indicators data of process, v8 heap and OS.
79 |
80 | ## Dashboard
81 |
82 | The dashboard , will calling at the child process way. It will create an Indicator instance and start a http server which provide a socket.io instance.
83 | Then bind the indicator with process IPC channel, to recive massage from parent process.
84 | And then bind the indicator with socket.io, to send messages while indicator attrbutes changed.
85 |
86 | ## The commication between Collector, Indicator and Dashboard
87 |
88 | 
89 |
90 | # Test
91 | Simply run:
92 |
93 | ```
94 | npm test
95 | ```
96 |
97 | # Some feature may be
98 | - [ ] Mutil process support
99 | - [ ] Report export
100 |
101 | # License
102 |
103 | [MIT License](LICENSE)
104 |
105 | Copyright (c) 2016-2017 JerryC
106 |
--------------------------------------------------------------------------------
/README_zh.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | [](https://travis-ci.org/JerryC8080/Memeye)
6 | [](https://badge.fury.io/js/memeye)
7 | [](http://packagequality.com/#?package=memeye)
8 | [](https://www.npmjs.com/package/memeye)
9 | [](https://github.com/JerryC8080/Memeye/blob/master/LICENSE)
10 |
11 | # Memeye
12 | [中文版](README_zh.md)
13 |
14 | # 介绍
15 | Memeye 是一个轻量级的 NodeJS 进程监控工具,它提供 进程内存、V8 堆空间内存、操作系统内存 三大维度的数据可视化展示。
16 | 前端部分,借助 [Vue2](https://github.com/vuejs/vue) 和 [ChartJS](https://github.com/chartjs/Chart.js) 提供了一个不错的动态展示面板。
17 | Memeye 在宿主进程中,只植入了一个简单的数据收集器,其他工作则启动一个子进程,交由子进程来进行。
18 | 这样做能把 Memeye 的代码对宿主进程的影响降到最低,以确保数据的真实性。
19 |
20 | ### 特点
21 | - 轻量级
22 | - 简单
23 | - 面向开发环境
24 | - 可视化
25 |
26 | *Note: Memeye 暂时只支持单进程,NodeJS 分布式进程还不适用,所以不建议在产品环境使用。*
27 |
28 | # 动机
29 | 总所周知,NodeJS 对内存是很敏感的。在去年 4 月我用 NodeJS 做的一个营销性的项目,在上线当天 PV 突破了 100W。
30 | 其中内存就呈现出持续上涨趋势,在排查问题的过程中,想寻找一个轻量级的,只要可视化的呈现内存使用情况的工具,无果。
31 | 然后就有了这个项目的想法,但当时由于繁忙只做出了一个 Demo 级别的,简单能用就发布了。
32 | 最近有时间,再次翻出来,重构改版,增加更多维度的数据展示。
33 |
34 | # Demo
35 | [See preview demo](http://jerryc8080.github.io/Memeye/) (也许需要翻墙)
36 |
37 | # 兼容性
38 | - Node v7.x
39 | - Node v6.x
40 |
41 | # 安装 & 使用
42 |
43 | 运行下面命令安装 :
44 |
45 | ```
46 | npm install memeye --save-dev
47 | ```
48 |
49 |
50 | 然后在你的代码中引入
51 |
52 | ```
53 | const memeye = require('memeye');
54 | memeye();
55 | ```
56 |
57 | 最后打开你的浏览器,输入下面地址:
58 |
59 | ```
60 | http://localhost:23333 //23333 port by defaul.
61 | ```
62 |
63 | 就这么简单!
64 |
65 | # Memeye 是如何工作的
66 |
67 | Memeye 有三个核心概念:Collector, Indicators, Dashboard。
68 | Collector 运行在宿主进程中(你的NodeJS进程),Indicator 和 Dashboard 运行在子进程中,这样可以尽量减少 Memeye 代码对你的宿主进程的影响。
69 |
70 | ## Collector
71 | Collector 会监听宿主进程,并且收集数据,然后通过 IPC 通信管道发送数据给子进程,交由子进程处理。
72 |
73 | ## Indicator
74 | Indicator 像一个状态机。当它的属性变化的时候,会触发相应事件。所以我们可以用它来处理收集回来的数据。
75 |
76 | ## Dashboard
77 | Dashboard 会以子进程的形式唤起。他会创建一个 Indicator 实例,以及启动一个集成 socket.io 的 Http 服务器。
78 | 然后绑定 Indicator 和进程通信管道,以接收父进程发过来的数据。
79 | 最后再绑定 Indicator 和 socket.io,这样可以在 Indicator 属性变化的时候发送数据给前端。
80 |
81 | ## Collector, Indicator, Dashboard 之间的通信
82 |
83 | 
84 |
85 |
86 | # 测试
87 |
88 | ```
89 | npm test
90 | ```
91 |
92 | # 在考虑的功能
93 | - [ ] 支持多进程
94 | - [ ] 支持导出报告
95 |
96 | # 许可
97 |
98 | [MIT License](LICENSE)
99 |
100 | Copyright (c) 2016-2017 JerryC
101 |
--------------------------------------------------------------------------------
/assets/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | memeye-client
8 |
9 |
10 |
11 |
12 |
13 |
14 | © 2014-2017 , Powered By
15 | Memeye
16 | , Author: JerryC
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/assets/memeye-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryC8080/Memeye/3ebd694b892896221b9eba28c5730c5d27be978b/assets/memeye-logo.png
--------------------------------------------------------------------------------
/assets/memeye.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryC8080/Memeye/3ebd694b892896221b9eba28c5730c5d27be978b/assets/memeye.ico
--------------------------------------------------------------------------------
/client/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["latest", {
4 | "es2015": { "modules": false }
5 | }]
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/client/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log
5 | yarn-error.log
6 |
--------------------------------------------------------------------------------
/client/README.md:
--------------------------------------------------------------------------------
1 | # memeye-client
2 |
3 | > A Vue.js project
4 |
5 | ## Build Setup
6 |
7 | ``` bash
8 | # install dependencies
9 | npm install
10 |
11 | # serve with hot reload at localhost:8080
12 | npm run dev
13 |
14 | # build for production with minification
15 | npm run build
16 | ```
17 |
18 | For detailed explanation on how things work, consult the [docs for vue-loader](http://vuejs.github.io/vue-loader).
19 |
--------------------------------------------------------------------------------
/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | memeye-client
8 |
9 |
10 |
11 |
12 |
13 |
14 | © 2014-2017 , Powered By
15 | Memeye
16 | , Author: JerryC
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "memeye-client",
3 | "description": "A Vue.js project",
4 | "version": "1.0.0",
5 | "author": "JerryC",
6 | "private": true,
7 | "scripts": {
8 | "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
9 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
10 | },
11 | "dependencies": {
12 | "socket.io-client": "^1.7.3",
13 | "vue": "^2.2.1",
14 | "vue-chartjs": "^2.4.1"
15 | },
16 | "devDependencies": {
17 | "babel-core": "^6.0.0",
18 | "babel-loader": "^6.0.0",
19 | "babel-preset-latest": "^6.0.0",
20 | "cross-env": "^3.0.0",
21 | "css-loader": "^0.25.0",
22 | "file-loader": "^0.9.0",
23 | "vue-loader": "^11.0.0",
24 | "vue-template-compiler": "^2.2.1",
25 | "webpack": "^2.2.0",
26 | "webpack-dev-server": "^2.2.0"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/client/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
23 |
24 |
51 |
--------------------------------------------------------------------------------
/client/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryC8080/Memeye/3ebd694b892896221b9eba28c5730c5d27be978b/client/src/assets/logo.png
--------------------------------------------------------------------------------
/client/src/assets/memeye.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JerryC8080/Memeye/3ebd694b892896221b9eba28c5730c5d27be978b/client/src/assets/memeye.ico
--------------------------------------------------------------------------------
/client/src/components/Memeye.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Wellcome to Memeye !
5 |
Indicators Panels
6 |
17 |
18 |
Process Memory Usage
19 |
23 |
24 |
V8 Heap Statistices
25 |
26 |
27 |
28 |
29 |
30 |
OS Statistices
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
166 |
167 |
--------------------------------------------------------------------------------
/client/src/components/Panel.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
20 |
21 |
22 |
23 |
34 |
35 |
49 |
50 |
--------------------------------------------------------------------------------
/client/src/components/PanelItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{title}}
5 |
6 |
7 | {{data}}
8 | {{unit.toUpperCase()}}
9 |
10 |
11 |
12 |
13 |
14 |
20 |
21 |
48 |
49 |
--------------------------------------------------------------------------------
/client/src/components/charts/OSCPUSUsedLine.js:
--------------------------------------------------------------------------------
1 | import { Line, mixins } from 'vue-chartjs';
2 | const { reactiveProp } = mixins;
3 |
4 | const records = 100;
5 |
6 | let dynamicData = {
7 | labels: new Array(records),
8 | cpus: null,
9 | }
10 |
11 | let colorPool = [
12 | '#F44336', // Red
13 | '#9C27B0', // Purple
14 | '#2196F3', // Blue
15 | '#8BC34A', // Light Green
16 | '#FFC107', // Amber
17 | '#CDDC39', // Lime
18 | '#00BCD4', // Cyan
19 | ];
20 |
21 | function caculateData(cpus) {
22 | let now = new Date();
23 |
24 | let data = {
25 | labels: dynamicData.labels,
26 | datasets: [],
27 | };
28 |
29 | // Initialize cpus
30 | if (!dynamicData.cpus) {
31 | dynamicData.cpus = cpus.map(() => new Array(100));
32 | }
33 |
34 | cpus.forEach(function (item, index) {
35 | let used = computedUsed(item.times);
36 | dynamicData.cpus[index].shift();
37 | dynamicData.cpus[index].push(used);
38 |
39 | data.datasets.push({
40 | label: `cpu ${index + 1}`,
41 | pointStyle: 'line',
42 | fill: false,
43 | borderColor: colorPool[index],
44 | backgroundColor: colorPool[index],
45 | data: dynamicData.cpus[index],
46 | });
47 | });
48 |
49 | return data;
50 | }
51 |
52 | function computedUsed(value) {
53 | var total = value.user + value.nice + value.sys + value.idle + value.irq;
54 | var cpu = ((total - value.idle) / total) * 100;
55 | return cpu;
56 | }
57 |
58 | let line = Line.extend({
59 | mixins: [reactiveProp],
60 | props: ['options'],
61 | mounted() {
62 | this.renderChart(this.chartData, {
63 | title: {
64 | display: true,
65 | text: 'CPUs Used',
66 | },
67 | tooltips: {
68 | callbacks: {
69 | label: (item, data) => {
70 | let label = data.datasets[item.datasetIndex].label;
71 | return label + ': ' + Math.floor(item.yLabel * 100) / 100 + ' %';
72 | }
73 | }
74 | },
75 | animation: false
76 | })
77 | }
78 | });
79 |
80 | line.caculateData = caculateData;
81 |
82 | export default line;
83 |
--------------------------------------------------------------------------------
/client/src/components/charts/OSMemoryLine.js:
--------------------------------------------------------------------------------
1 | import { Line, mixins } from 'vue-chartjs'
2 | const { reactiveProp } = mixins
3 |
4 | const records = 100;
5 |
6 | let dynamicData = {
7 | labels: new Array(records),
8 | freeMemData: new Array(records),
9 | usedMemData: new Array(records),
10 | }
11 |
12 | function caculateData(type, value) {
13 | let now = new Date();
14 |
15 | dynamicData[`${type}Data`].shift();
16 | dynamicData[`${type}Data`].push(value / 1024 / 1024);
17 |
18 | return {
19 | labels: dynamicData.labels,
20 | datasets: [
21 | {
22 | label: 'freeMem',
23 | pointStyle: 'line',
24 | borderColor: "rgba(54, 162, 235, 1)",
25 | backgroundColor: 'rgba(54, 162, 235, 0.4)',
26 | data: dynamicData.freeMemData,
27 | },
28 | {
29 | label: 'usedMem',
30 | pointStyle: 'line',
31 | borderColor: "rgba(255, 99, 132, 1)",
32 | backgroundColor: 'rgba(255, 99, 132, 0.4)',
33 | data: dynamicData.usedMemData,
34 | }
35 | ]
36 | };
37 | }
38 |
39 | let line = Line.extend({
40 | mixins: [reactiveProp],
41 | props: ['options'],
42 | mounted() {
43 | this.renderChart(this.chartData, {
44 | title: {
45 | display: true,
46 | text: 'OS Memory Stat',
47 | },
48 | tooltips: {
49 | callbacks: {
50 | label: (item) => (Math.floor(item.yLabel * 100) / 100 + ' MB')
51 | }
52 | },
53 | animation: false
54 | })
55 | }
56 | });
57 |
58 | line.caculateData = caculateData;
59 |
60 | export default line;
61 |
62 |
--------------------------------------------------------------------------------
/client/src/components/charts/OSMemoryPie.js:
--------------------------------------------------------------------------------
1 | import { Pie, mixins } from 'vue-chartjs';
2 | const { reactiveProp } = mixins;
3 |
4 | function caculateData(freeMem, usedMem) {
5 | return {
6 | labels: [
7 | "freeMem",
8 | "usedMem",
9 | ],
10 | datasets: [
11 | {
12 | data: [freeMem, usedMem],
13 | backgroundColor: [
14 | "#36A2EB",
15 | "#FF6384",
16 | ],
17 | hoverBackgroundColor: [
18 | "#36A2EB",
19 | "#FF6384",
20 | ]
21 | }]
22 | };
23 | }
24 |
25 | let pie = Pie.extend({
26 | mixins: [reactiveProp],
27 | props: ['options'],
28 | mounted() {
29 | this.renderChart(this.chartData, {
30 | title: {
31 | display: true,
32 | text: 'OS Memory Stat',
33 | },
34 | tooltips: {
35 | callbacks: {
36 | label: (item, data) => {
37 | let val = data.datasets[item.datasetIndex].data[item.index];
38 | return Math.floor(val / 1024 / 1024 * 100) / 100 + ' MB';
39 | }
40 | }
41 | },
42 | animation: false,
43 | });
44 | }
45 | });
46 | pie.caculateData = caculateData;
47 |
48 | export default pie;
--------------------------------------------------------------------------------
/client/src/components/charts/ProcessDoughnut.js:
--------------------------------------------------------------------------------
1 | import { Doughnut, mixins } from 'vue-chartjs'
2 | const { reactiveProp } = mixins
3 |
4 | function caculateData(heapFree, heapUsed) {
5 | heapFree = heapFree / 1024 / 1024;
6 | heapUsed = heapUsed / 1024 / 1024;
7 |
8 | return {
9 | labels: [
10 | "heapFree",
11 | "heapUsed",
12 | ],
13 | datasets: [
14 | {
15 | data: [heapFree, heapUsed],
16 | backgroundColor: [
17 | "#36A2EB",
18 | "#FF6384",
19 | ],
20 | hoverBackgroundColor: [
21 | "#36A2EB",
22 | "#FF6384",
23 | ]
24 | }]
25 | };
26 | }
27 |
28 | let doughnut = Doughnut.extend({
29 | mixins: [reactiveProp],
30 | props: ['options'],
31 | mounted() {
32 | this.renderChart(this.chartData, {
33 | title: {
34 | display: true,
35 | text: 'Process Memory Stat',
36 | },
37 | tooltips: {
38 | callbacks: {
39 | label: (item, data) => {
40 | let val = data.datasets[item.datasetIndex].data[item.index];
41 | return Math.floor(val * 100) / 100 + ' MB';
42 | }
43 | }
44 | },
45 | animation: false,
46 | })
47 | }
48 | });
49 |
50 | doughnut.caculateData = caculateData;
51 |
52 | export default doughnut;
--------------------------------------------------------------------------------
/client/src/components/charts/ProcessLine.js:
--------------------------------------------------------------------------------
1 | import { Line, mixins } from 'vue-chartjs'
2 | const { reactiveProp } = mixins
3 | const records = 100; // second;
4 |
5 | let dynamicData = {
6 | labels: new Array(records),
7 | rssData: new Array(records),
8 | heapTotalData: new Array(records),
9 | heapUsedData: new Array(records),
10 | }
11 |
12 | function caculateData({ type, value }) {
13 |
14 | // dynamicData.labels.shift();
15 | // dynamicData.labels.push(new Date());
16 |
17 | dynamicData[`${type}Data`].shift();
18 | dynamicData[`${type}Data`].push(value / 1024 / 1024);
19 |
20 | return {
21 | labels: dynamicData.labels,
22 | datasets: [
23 | {
24 | label: 'heapUsed',
25 | pointStyle: 'line',
26 | // fill: false,
27 | borderColor: "rgba(255, 99, 132, 1)",
28 | backgroundColor: 'rgba(255, 99, 132, 0.4)',
29 | data: dynamicData.heapUsedData,
30 | },
31 | {
32 | label: 'heapTotal',
33 | pointStyle: 'line',
34 | // fill: false,
35 | borderColor: "rgba(54, 162, 235, 1)",
36 | backgroundColor: 'rgba(54, 162, 235, 0.4)',
37 | data: dynamicData.heapTotalData,
38 | },
39 | {
40 | label: 'rss',
41 | pointStyle: 'line',
42 | // fill: false,
43 | borderColor: "rgba(53, 221, 101, 1)",
44 | backgroundColor: 'rgba(53, 221, 101, 0.4)',
45 | data: dynamicData.rssData,
46 | },
47 | ]
48 | };
49 | }
50 |
51 | let line = Line.extend({
52 | mixins: [reactiveProp],
53 | props: ['options'],
54 | mounted() {
55 | this.renderChart(this.chartData, {
56 | title: {
57 | display: true,
58 | text: 'Process Memory Stat',
59 | },
60 | tooltips: {
61 | callbacks: {
62 | label: (item) => (Math.floor(item.yLabel * 100) / 100 + ' MB')
63 | }
64 | },
65 | animation: false
66 | })
67 | }
68 | });
69 |
70 | line.caculateData = caculateData;
71 |
72 | export default line;
73 |
74 |
--------------------------------------------------------------------------------
/client/src/components/charts/V8HeapSpaceBar.js:
--------------------------------------------------------------------------------
1 | import { Bar, mixins } from 'vue-chartjs';
2 | const { reactiveProp } = mixins;
3 |
4 | let space = {
5 | newSpace: 0,
6 | oldSpace: 0,
7 | codeSpace: 0,
8 | mapSpace: 0,
9 | largeObjectSpace: 0,
10 | }
11 |
12 | function caculateData(type, val) {
13 | space[type] = val;
14 | return {
15 | labels: [
16 | 'newSpace',
17 | 'oldSpace',
18 | 'codeSpace',
19 | 'mapSpace',
20 | 'largeObjectSpace',
21 | ],
22 | datasets: [
23 | {
24 | label: 'Space Used Percent',
25 | backgroundColor: [
26 | '#9CCC65',
27 | // 'rgba(156, 204, 101, 0.8)',
28 | '#42A5F5',
29 | // 'rgba(33, 150, 243, 0.8)',
30 | '#5C6BC0',
31 | '#FFCA28',
32 | '#8D6E63',
33 | ],
34 | borderColor: [
35 | '#9CCC65',
36 | '#42A5F5',
37 | '#5C6BC0',
38 | '#FFCA28',
39 | '#8D6E63',
40 | ],
41 | borderWidth: 2,
42 | data: [
43 | space.newSpace,
44 | space.oldSpace,
45 | space.codeSpace,
46 | space.mapSpace,
47 | space.largeObjectSpace,
48 | ],
49 | },
50 | ]
51 | };
52 | }
53 |
54 | let bar = Bar.extend({
55 | mixins: [reactiveProp],
56 | props: ['options'],
57 | mounted() {
58 | this.renderChart(this.chartData, {
59 | legend: {
60 | display: false,
61 | },
62 | tooltips: {
63 | callbacks: {
64 | label: function (item, data) {
65 | return Math.floor(item.xLabel * 100) / 100 + ' %';
66 | }
67 | }
68 | },
69 | scales: {
70 | xAxes: [{
71 | ticks: {
72 | min: 0,
73 | max: 100
74 | }
75 | }]
76 | },
77 | title: {
78 | display: true,
79 | text: 'Space Used Percent',
80 | },
81 | animation: false,
82 | }, 'horizontalBar');
83 | }
84 | });
85 | bar.caculateData = caculateData;
86 |
87 | export default bar;
--------------------------------------------------------------------------------
/client/src/components/charts/V8HeapSpacePie.js:
--------------------------------------------------------------------------------
1 | import { Pie, mixins } from 'vue-chartjs';
2 | const { reactiveProp } = mixins;
3 |
4 | let space = {
5 | newSpace: 0,
6 | oldSpace: 0,
7 | codeSpace: 0,
8 | mapSpace: 0,
9 | largeObjectSpace: 0,
10 | }
11 |
12 | function caculateData(type, val) {
13 | space[type] = val;
14 | return {
15 | labels: [
16 | 'newSpace',
17 | 'oldSpace',
18 | 'codeSpace',
19 | 'mapSpace',
20 | 'largeObjectSpace',
21 | ],
22 | datasets: [
23 | {
24 | data: [
25 | space.newSpace,
26 | space.oldSpace,
27 | space.codeSpace,
28 | space.mapSpace,
29 | space.largeObjectSpace,
30 | ],
31 | backgroundColor: [
32 | '#9CCC65',
33 | '#42A5F5',
34 | '#5C6BC0',
35 | '#FFCA28',
36 | '#8D6E63',
37 | ],
38 | hoverBackgroundColor: [
39 | '#7CB342',
40 | '#1E88E5',
41 | '#3949AB',
42 | '#FFB300',
43 | '#6D4C41',
44 | ]
45 | }]
46 | };
47 | }
48 |
49 | let pie = Pie.extend({
50 | mixins: [reactiveProp],
51 | props: ['options'],
52 | mounted() {
53 | this.renderChart(this.chartData, {
54 | title: {
55 | display: true,
56 | text: 'V8 Heap Sapce',
57 | },
58 | tooltips: {
59 | callbacks: {
60 | label: (item, data) => {
61 | let val = data.datasets[item.datasetIndex].data[item.index];
62 | return Math.floor(val / 1024 * 100) / 100 + ' KB';
63 | }
64 | }
65 | },
66 | animation: false,
67 | });
68 | }
69 | });
70 | pie.caculateData = caculateData;
71 |
72 | export default pie;
--------------------------------------------------------------------------------
/client/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | window.vm = new Vue({
5 | el: '#app',
6 | render: h => h(App)
7 | })
--------------------------------------------------------------------------------
/client/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var webpack = require('webpack')
3 |
4 | let config = {
5 | entry: './src/main.js',
6 | output: {
7 | path: path.resolve(__dirname, './dist'),
8 | publicPath: '/dist/',
9 | filename: 'build.js'
10 | },
11 | module: {
12 | rules: [
13 | {
14 | test: /\.vue$/,
15 | loader: 'vue-loader',
16 | options: {
17 | loaders: {
18 | }
19 | // other vue-loader options go here
20 | }
21 | },
22 | {
23 | test: /\.js$/,
24 | loader: 'babel-loader',
25 | exclude: /node_modules/
26 | },
27 | {
28 | test: /\.(png|jpg|gif|svg)$/,
29 | loader: 'file-loader',
30 | options: {
31 | name: '[name].[ext]?[hash]'
32 | }
33 | }
34 | ]
35 | },
36 | resolve: {
37 | alias: {
38 | 'vue$': 'vue/dist/vue.esm.js'
39 | }
40 | },
41 | devServer: {
42 | historyApiFallback: true,
43 | noInfo: true
44 | },
45 | performance: {
46 | hints: false
47 | },
48 | devtool: '#eval-source-map'
49 | }
50 |
51 | if (process.env.NODE_ENV === 'production') {
52 | config.output.path = path.resolve(__dirname, '../assets/dist'),
53 | module.exports.devtool = '#source-map'
54 | // http://vue-loader.vuejs.org/en/workflow/production.html
55 | module.exports.plugins = (module.exports.plugins || []).concat([
56 | new webpack.DefinePlugin({
57 | 'process.env': {
58 | NODE_ENV: '"production"'
59 | }
60 | }),
61 | new webpack.optimize.UglifyJsPlugin({
62 | sourceMap: true,
63 | compress: {
64 | warnings: false
65 | }
66 | }),
67 | new webpack.LoaderOptionsPlugin({
68 | minimize: true
69 | })
70 | ])
71 | }
72 |
73 | module.exports = config;
74 |
--------------------------------------------------------------------------------
/coverage/coverage.json:
--------------------------------------------------------------------------------
1 | {"/Users/JerryC/Workspace/jc-repository/Memeye/index.js":{"path":"/Users/JerryC/Workspace/jc-repository/Memeye/index.js","s":{"1":1},"b":{},"f":{},"fnMap":{},"statementMap":{"1":{"start":{"line":1,"column":0},"end":{"line":1,"column":43}}},"branchMap":{}},"/Users/JerryC/Workspace/jc-repository/Memeye/src/index.js":{"path":"/Users/JerryC/Workspace/jc-repository/Memeye/src/index.js","s":{"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":0,"16":1,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0},"b":{"1":[1,0]},"f":{"1":1},"fnMap":{"1":{"name":"(anonymous_1)","line":14,"loc":{"start":{"line":14,"column":17},"end":{"line":14,"column":55}}}},"statementMap":{"1":{"start":{"line":8,"column":0},"end":{"line":8,"column":29}},"2":{"start":{"line":9,"column":0},"end":{"line":9,"column":47}},"3":{"start":{"line":10,"column":0},"end":{"line":10,"column":48}},"4":{"start":{"line":11,"column":0},"end":{"line":11,"column":55}},"5":{"start":{"line":12,"column":0},"end":{"line":12,"column":42}},"6":{"start":{"line":14,"column":0},"end":{"line":43,"column":1}},"7":{"start":{"line":15,"column":4},"end":{"line":15,"column":34}},"8":{"start":{"line":15,"column":13},"end":{"line":15,"column":34}},"9":{"start":{"line":17,"column":4},"end":{"line":17,"column":43}},"10":{"start":{"line":19,"column":4},"end":{"line":19,"column":66}},"11":{"start":{"line":21,"column":4},"end":{"line":21,"column":49}},"12":{"start":{"line":23,"column":4},"end":{"line":23,"column":52}},"13":{"start":{"line":24,"column":4},"end":{"line":24,"column":22}},"14":{"start":{"line":27,"column":4},"end":{"line":27,"column":54}},"15":{"start":{"line":27,"column":29},"end":{"line":27,"column":52}},"16":{"start":{"line":30,"column":4},"end":{"line":42,"column":7}},"17":{"start":{"line":33,"column":8},"end":{"line":33,"column":75}},"18":{"start":{"line":34,"column":8},"end":{"line":34,"column":66}},"19":{"start":{"line":35,"column":8},"end":{"line":35,"column":32}},"20":{"start":{"line":39,"column":8},"end":{"line":39,"column":65}},"21":{"start":{"line":40,"column":8},"end":{"line":40,"column":52}},"22":{"start":{"line":41,"column":8},"end":{"line":41,"column":25}}},"branchMap":{"1":{"line":15,"type":"if","locations":[{"start":{"line":15,"column":4},"end":{"line":15,"column":4}},{"start":{"line":15,"column":4},"end":{"line":15,"column":4}}]}}},"/Users/JerryC/Workspace/jc-repository/Memeye/src/lib/Collector.js":{"path":"/Users/JerryC/Workspace/jc-repository/Memeye/src/lib/Collector.js","s":{"1":1,"2":1,"3":1,"4":1,"5":2,"6":2,"7":2,"8":1,"9":1,"10":1,"11":3,"12":3,"13":1,"14":1,"15":2,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1},"b":{"1":[1,2],"2":[1,0],"3":[1,0]},"f":{"1":2,"2":1,"3":3},"fnMap":{"1":{"name":"Collector","line":10,"loc":{"start":{"line":10,"column":0},"end":{"line":10,"column":57}}},"2":{"name":"(anonymous_2)","line":16,"loc":{"start":{"line":16,"column":27},"end":{"line":16,"column":39}}},"3":{"name":"(anonymous_3)","line":20,"loc":{"start":{"line":20,"column":28},"end":{"line":20,"column":40}}}},"statementMap":{"1":{"start":{"line":6,"column":0},"end":{"line":6,"column":25}},"2":{"start":{"line":7,"column":0},"end":{"line":7,"column":25}},"3":{"start":{"line":8,"column":0},"end":{"line":8,"column":38}},"4":{"start":{"line":10,"column":0},"end":{"line":14,"column":1}},"5":{"start":{"line":11,"column":4},"end":{"line":11,"column":31}},"6":{"start":{"line":12,"column":4},"end":{"line":12,"column":25}},"7":{"start":{"line":13,"column":4},"end":{"line":13,"column":31}},"8":{"start":{"line":16,"column":0},"end":{"line":18,"column":1}},"9":{"start":{"line":17,"column":4},"end":{"line":17,"column":33}},"10":{"start":{"line":20,"column":0},"end":{"line":66,"column":1}},"11":{"start":{"line":21,"column":4},"end":{"line":21,"column":20}},"12":{"start":{"line":23,"column":4},"end":{"line":26,"column":5}},"13":{"start":{"line":24,"column":8},"end":{"line":24,"column":52}},"14":{"start":{"line":25,"column":8},"end":{"line":25,"column":15}},"15":{"start":{"line":28,"column":4},"end":{"line":65,"column":23}},"16":{"start":{"line":31,"column":8},"end":{"line":31,"column":48}},"17":{"start":{"line":32,"column":8},"end":{"line":35,"column":9}},"18":{"start":{"line":36,"column":8},"end":{"line":40,"column":9}},"19":{"start":{"line":41,"column":8},"end":{"line":54,"column":9}},"20":{"start":{"line":57,"column":8},"end":{"line":59,"column":9}},"21":{"start":{"line":58,"column":12},"end":{"line":58,"column":38}},"22":{"start":{"line":61,"column":8},"end":{"line":63,"column":9}},"23":{"start":{"line":62,"column":12},"end":{"line":62,"column":145}},"24":{"start":{"line":68,"column":0},"end":{"line":68,"column":27}}},"branchMap":{"1":{"line":23,"type":"if","locations":[{"start":{"line":23,"column":4},"end":{"line":23,"column":4}},{"start":{"line":23,"column":4},"end":{"line":23,"column":4}}]},"2":{"line":57,"type":"if","locations":[{"start":{"line":57,"column":8},"end":{"line":57,"column":8}},{"start":{"line":57,"column":8},"end":{"line":57,"column":8}}]},"3":{"line":61,"type":"if","locations":[{"start":{"line":61,"column":8},"end":{"line":61,"column":8}},{"start":{"line":61,"column":8},"end":{"line":61,"column":8}}]}}},"/Users/JerryC/Workspace/jc-repository/Memeye/src/lib/Logger.js":{"path":"/Users/JerryC/Workspace/jc-repository/Memeye/src/lib/Logger.js","s":{"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":2,"11":0,"12":2,"13":1,"14":2,"15":1,"16":0,"17":0,"18":1,"19":0,"20":0,"21":1,"22":2,"23":2,"24":1,"25":1,"26":1,"27":1},"b":{"1":[0,2],"2":[2,1],"3":[1,1],"4":[0,0],"5":[0,0],"6":[2,0],"7":[1,0]},"f":{"1":1,"2":2,"3":0,"4":0,"5":2,"6":1},"fnMap":{"1":{"name":"Logger","line":19,"loc":{"start":{"line":19,"column":0},"end":{"line":19,"column":40}}},"2":{"name":"(anonymous_2)","line":25,"loc":{"start":{"line":25,"column":28},"end":{"line":25,"column":45}}},"3":{"name":"(anonymous_3)","line":31,"loc":{"start":{"line":31,"column":25},"end":{"line":31,"column":40}}},"4":{"name":"(anonymous_4)","line":35,"loc":{"start":{"line":35,"column":24},"end":{"line":35,"column":39}}},"5":{"name":"(anonymous_5)","line":39,"loc":{"start":{"line":39,"column":24},"end":{"line":39,"column":39}}},"6":{"name":"(anonymous_6)","line":43,"loc":{"start":{"line":43,"column":25},"end":{"line":43,"column":40}}}},"statementMap":{"1":{"start":{"line":1,"column":0},"end":{"line":1,"column":38}},"2":{"start":{"line":3,"column":0},"end":{"line":8,"column":3}},"3":{"start":{"line":10,"column":0},"end":{"line":15,"column":1}},"4":{"start":{"line":17,"column":0},"end":{"line":17,"column":24}},"5":{"start":{"line":19,"column":0},"end":{"line":23,"column":1}},"6":{"start":{"line":20,"column":4},"end":{"line":20,"column":36}},"7":{"start":{"line":21,"column":4},"end":{"line":21,"column":25}},"8":{"start":{"line":22,"column":4},"end":{"line":22,"column":29}},"9":{"start":{"line":25,"column":0},"end":{"line":29,"column":1}},"10":{"start":{"line":26,"column":4},"end":{"line":26,"column":74}},"11":{"start":{"line":26,"column":64},"end":{"line":26,"column":74}},"12":{"start":{"line":27,"column":4},"end":{"line":27,"column":59}},"13":{"start":{"line":27,"column":35},"end":{"line":27,"column":59}},"14":{"start":{"line":28,"column":4},"end":{"line":28,"column":30}},"15":{"start":{"line":31,"column":0},"end":{"line":33,"column":1}},"16":{"start":{"line":32,"column":4},"end":{"line":32,"column":88}},"17":{"start":{"line":32,"column":41},"end":{"line":32,"column":88}},"18":{"start":{"line":35,"column":0},"end":{"line":37,"column":1}},"19":{"start":{"line":36,"column":4},"end":{"line":36,"column":86}},"20":{"start":{"line":36,"column":40},"end":{"line":36,"column":86}},"21":{"start":{"line":39,"column":0},"end":{"line":41,"column":1}},"22":{"start":{"line":40,"column":4},"end":{"line":40,"column":86}},"23":{"start":{"line":40,"column":40},"end":{"line":40,"column":86}},"24":{"start":{"line":43,"column":0},"end":{"line":45,"column":1}},"25":{"start":{"line":44,"column":4},"end":{"line":44,"column":88}},"26":{"start":{"line":44,"column":41},"end":{"line":44,"column":88}},"27":{"start":{"line":47,"column":0},"end":{"line":47,"column":44}}},"branchMap":{"1":{"line":26,"type":"if","locations":[{"start":{"line":26,"column":4},"end":{"line":26,"column":4}},{"start":{"line":26,"column":4},"end":{"line":26,"column":4}}]},"2":{"line":26,"type":"binary-expr","locations":[{"start":{"line":26,"column":8},"end":{"line":26,"column":33}},{"start":{"line":26,"column":37},"end":{"line":26,"column":62}}]},"3":{"line":27,"type":"if","locations":[{"start":{"line":27,"column":4},"end":{"line":27,"column":4}},{"start":{"line":27,"column":4},"end":{"line":27,"column":4}}]},"4":{"line":32,"type":"if","locations":[{"start":{"line":32,"column":4},"end":{"line":32,"column":4}},{"start":{"line":32,"column":4},"end":{"line":32,"column":4}}]},"5":{"line":36,"type":"if","locations":[{"start":{"line":36,"column":4},"end":{"line":36,"column":4}},{"start":{"line":36,"column":4},"end":{"line":36,"column":4}}]},"6":{"line":40,"type":"if","locations":[{"start":{"line":40,"column":4},"end":{"line":40,"column":4}},{"start":{"line":40,"column":4},"end":{"line":40,"column":4}}]},"7":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":4}},{"start":{"line":44,"column":4},"end":{"line":44,"column":4}}]}}},"/Users/JerryC/Workspace/jc-repository/Memeye/src/lib/Indicators.js":{"path":"/Users/JerryC/Workspace/jc-repository/Memeye/src/lib/Indicators.js","s":{"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":2,"11":2,"12":2,"13":2,"14":2,"15":2,"16":2,"17":1,"18":2,"19":1},"b":{},"f":{"1":1,"2":2,"3":2,"4":1},"fnMap":{"1":{"name":"Indicators","line":11,"loc":{"start":{"line":11,"column":0},"end":{"line":11,"column":32}}},"2":{"name":"setWatcher","line":26,"loc":{"start":{"line":26,"column":34},"end":{"line":26,"column":66}}},"3":{"name":"(anonymous_3)","line":34,"loc":{"start":{"line":34,"column":17},"end":{"line":34,"column":34}}},"4":{"name":"(anonymous_4)","line":38,"loc":{"start":{"line":38,"column":17},"end":{"line":38,"column":29}}}},"statementMap":{"1":{"start":{"line":7,"column":0},"end":{"line":7,"column":33}},"2":{"start":{"line":8,"column":0},"end":{"line":8,"column":29}},"3":{"start":{"line":11,"column":0},"end":{"line":20,"column":1}},"4":{"start":{"line":12,"column":4},"end":{"line":12,"column":35}},"5":{"start":{"line":15,"column":4},"end":{"line":15,"column":20}},"6":{"start":{"line":16,"column":4},"end":{"line":16,"column":42}},"7":{"start":{"line":19,"column":4},"end":{"line":19,"column":43}},"8":{"start":{"line":23,"column":0},"end":{"line":23,"column":47}},"9":{"start":{"line":26,"column":0},"end":{"line":46,"column":1}},"10":{"start":{"line":27,"column":4},"end":{"line":27,"column":24}},"11":{"start":{"line":28,"column":4},"end":{"line":28,"column":20}},"12":{"start":{"line":31,"column":4},"end":{"line":43,"column":7}},"13":{"start":{"line":32,"column":8},"end":{"line":32,"column":42}},"14":{"start":{"line":33,"column":8},"end":{"line":42,"column":9}},"15":{"start":{"line":35,"column":16},"end":{"line":35,"column":50}},"16":{"start":{"line":36,"column":16},"end":{"line":36,"column":40}},"17":{"start":{"line":39,"column":16},"end":{"line":39,"column":39}},"18":{"start":{"line":45,"column":4},"end":{"line":45,"column":46}},"19":{"start":{"line":48,"column":0},"end":{"line":48,"column":28}}},"branchMap":{}}}
--------------------------------------------------------------------------------
/coverage/lcov-report/base.css:
--------------------------------------------------------------------------------
1 | body, html {
2 | margin:0; padding: 0;
3 | height: 100%;
4 | }
5 | body {
6 | font-family: Helvetica Neue, Helvetica, Arial;
7 | font-size: 14px;
8 | color:#333;
9 | }
10 | .small { font-size: 12px; }
11 | *, *:after, *:before {
12 | -webkit-box-sizing:border-box;
13 | -moz-box-sizing:border-box;
14 | box-sizing:border-box;
15 | }
16 | h1 { font-size: 20px; margin: 0;}
17 | h2 { font-size: 14px; }
18 | pre {
19 | font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
20 | margin: 0;
21 | padding: 0;
22 | -moz-tab-size: 2;
23 | -o-tab-size: 2;
24 | tab-size: 2;
25 | }
26 | a { color:#0074D9; text-decoration:none; }
27 | a:hover { text-decoration:underline; }
28 | .strong { font-weight: bold; }
29 | .space-top1 { padding: 10px 0 0 0; }
30 | .pad2y { padding: 20px 0; }
31 | .pad1y { padding: 10px 0; }
32 | .pad2x { padding: 0 20px; }
33 | .pad2 { padding: 20px; }
34 | .pad1 { padding: 10px; }
35 | .space-left2 { padding-left:55px; }
36 | .space-right2 { padding-right:20px; }
37 | .center { text-align:center; }
38 | .clearfix { display:block; }
39 | .clearfix:after {
40 | content:'';
41 | display:block;
42 | height:0;
43 | clear:both;
44 | visibility:hidden;
45 | }
46 | .fl { float: left; }
47 | @media only screen and (max-width:640px) {
48 | .col3 { width:100%; max-width:100%; }
49 | .hide-mobile { display:none!important; }
50 | }
51 |
52 | .quiet {
53 | color: #7f7f7f;
54 | color: rgba(0,0,0,0.5);
55 | }
56 | .quiet a { opacity: 0.7; }
57 |
58 | .fraction {
59 | font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
60 | font-size: 10px;
61 | color: #555;
62 | background: #E8E8E8;
63 | padding: 4px 5px;
64 | border-radius: 3px;
65 | vertical-align: middle;
66 | }
67 |
68 | div.path a:link, div.path a:visited { color: #333; }
69 | table.coverage {
70 | border-collapse: collapse;
71 | margin: 10px 0 0 0;
72 | padding: 0;
73 | }
74 |
75 | table.coverage td {
76 | margin: 0;
77 | padding: 0;
78 | vertical-align: top;
79 | }
80 | table.coverage td.line-count {
81 | text-align: right;
82 | padding: 0 5px 0 20px;
83 | }
84 | table.coverage td.line-coverage {
85 | text-align: right;
86 | padding-right: 10px;
87 | min-width:20px;
88 | }
89 |
90 | table.coverage td span.cline-any {
91 | display: inline-block;
92 | padding: 0 5px;
93 | width: 100%;
94 | }
95 | .missing-if-branch {
96 | display: inline-block;
97 | margin-right: 5px;
98 | border-radius: 3px;
99 | position: relative;
100 | padding: 0 4px;
101 | background: #333;
102 | color: yellow;
103 | }
104 |
105 | .skip-if-branch {
106 | display: none;
107 | margin-right: 10px;
108 | position: relative;
109 | padding: 0 4px;
110 | background: #ccc;
111 | color: white;
112 | }
113 | .missing-if-branch .typ, .skip-if-branch .typ {
114 | color: inherit !important;
115 | }
116 | .coverage-summary {
117 | border-collapse: collapse;
118 | width: 100%;
119 | }
120 | .coverage-summary tr { border-bottom: 1px solid #bbb; }
121 | .keyline-all { border: 1px solid #ddd; }
122 | .coverage-summary td, .coverage-summary th { padding: 10px; }
123 | .coverage-summary tbody { border: 1px solid #bbb; }
124 | .coverage-summary td { border-right: 1px solid #bbb; }
125 | .coverage-summary td:last-child { border-right: none; }
126 | .coverage-summary th {
127 | text-align: left;
128 | font-weight: normal;
129 | white-space: nowrap;
130 | }
131 | .coverage-summary th.file { border-right: none !important; }
132 | .coverage-summary th.pct { }
133 | .coverage-summary th.pic,
134 | .coverage-summary th.abs,
135 | .coverage-summary td.pct,
136 | .coverage-summary td.abs { text-align: right; }
137 | .coverage-summary td.file { white-space: nowrap; }
138 | .coverage-summary td.pic { min-width: 120px !important; }
139 | .coverage-summary tfoot td { }
140 |
141 | .coverage-summary .sorter {
142 | height: 10px;
143 | width: 7px;
144 | display: inline-block;
145 | margin-left: 0.5em;
146 | background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
147 | }
148 | .coverage-summary .sorted .sorter {
149 | background-position: 0 -20px;
150 | }
151 | .coverage-summary .sorted-desc .sorter {
152 | background-position: 0 -10px;
153 | }
154 | .status-line { height: 10px; }
155 | /* dark red */
156 | .red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
157 | .low .chart { border:1px solid #C21F39 }
158 | /* medium red */
159 | .cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
160 | /* light red */
161 | .low, .cline-no { background:#FCE1E5 }
162 | /* light green */
163 | .high, .cline-yes { background:rgb(230,245,208) }
164 | /* medium green */
165 | .cstat-yes { background:rgb(161,215,106) }
166 | /* dark green */
167 | .status-line.high, .high .cover-fill { background:rgb(77,146,33) }
168 | .high .chart { border:1px solid rgb(77,146,33) }
169 | /* dark yellow (gold) */
170 | .medium .chart { border:1px solid #f9cd0b; }
171 | .status-line.medium, .medium .cover-fill { background: #f9cd0b; }
172 | /* light yellow */
173 | .medium { background: #fff4c2; }
174 | /* light gray */
175 | span.cline-neutral { background: #eaeaea; }
176 |
177 | .cbranch-no { background: yellow !important; color: #111; }
178 |
179 | .cstat-skip { background: #ddd; color: #111; }
180 | .fstat-skip { background: #ddd; color: #111 !important; }
181 | .cbranch-skip { background: #ddd !important; color: #111; }
182 |
183 |
184 | .cover-fill, .cover-empty {
185 | display:inline-block;
186 | height: 12px;
187 | }
188 | .chart {
189 | line-height: 0;
190 | }
191 | .cover-empty {
192 | background: white;
193 | }
194 | .cover-full {
195 | border-right: none !important;
196 | }
197 | pre.prettyprint {
198 | border: none !important;
199 | padding: 0 !important;
200 | margin: 0 !important;
201 | }
202 | .com { color: #999 !important; }
203 | .ignore-none { color: #999; font-weight: normal; }
204 |
205 | .wrapper {
206 | min-height: 100%;
207 | height: auto !important;
208 | height: 100%;
209 | margin: 0 auto -48px;
210 | }
211 | .footer, .push {
212 | height: 48px;
213 | }
214 |
--------------------------------------------------------------------------------
/coverage/lcov-report/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for All files
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 | /
20 |
21 |
22 |
23 | 87.1%
24 | Statements
25 | 81/93
26 |
27 |
28 | 54.55%
29 | Branches
30 | 12/22
31 |
32 |
33 | 85.71%
34 | Functions
35 | 12/14
36 |
37 |
38 | 90.59%
39 | Lines
40 | 77/85
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | File
50 |
51 | Statements
52 |
53 | Branches
54 |
55 | Functions
56 |
57 | Lines
58 |
59 |
60 |
61 |
62 | Memeye/
63 |
64 | 100%
65 | 1/1
66 | 100%
67 | 0/0
68 | 100%
69 | 0/0
70 | 100%
71 | 1/1
72 |
73 |
74 |
75 | Memeye/src/
76 |
77 | 68.18%
78 | 15/22
79 | 50%
80 | 1/2
81 | 100%
82 | 1/1
83 | 70%
84 | 14/20
85 |
86 |
87 |
88 | Memeye/src/lib/
89 |
90 | 92.86%
91 | 65/70
92 | 55%
93 | 11/20
94 | 84.62%
95 | 11/13
96 | 96.88%
97 | 62/64
98 |
99 |
100 |
101 |
102 |
103 |
104 |
108 |
109 |
110 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/coverage/lcov-report/lib/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for lib/
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 100%
24 | Statements
25 | 38/38
26 |
27 |
28 | 100%
29 | Branches
30 | 2/2
31 |
32 |
33 | 100%
34 | Functions
35 | 7/7
36 |
37 |
38 | 100%
39 | Lines
40 | 38/38
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | File
50 |
51 | Statements
52 |
53 | Branches
54 |
55 | Functions
56 |
57 | Lines
58 |
59 |
60 |
61 |
62 | Collector.js
63 |
64 | 100%
65 | 19/19
66 | 100%
67 | 2/2
68 | 100%
69 | 3/3
70 | 100%
71 | 19/19
72 |
73 |
74 |
75 | Indicators.js
76 |
77 | 100%
78 | 19/19
79 | 100%
80 | 0/0
81 | 100%
82 | 4/4
83 | 100%
84 | 19/19
85 |
86 |
87 |
88 |
89 |
90 |
91 |
95 |
96 |
97 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/coverage/lcov-report/prettify.css:
--------------------------------------------------------------------------------
1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
2 |
--------------------------------------------------------------------------------
/coverage/lcov-report/prettify.js:
--------------------------------------------------------------------------------
1 | window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^