Skip to content

Commit

Permalink
#Changed#
Browse files Browse the repository at this point in the history
Upgrade method canary to 0.15.2
Add pageload lifecycle cost time to dashabord
  • Loading branch information
hui.zhao committed Mar 6, 2020
1 parent b0361df commit c404dee
Show file tree
Hide file tree
Showing 23 changed files with 1,265 additions and 200 deletions.
1,048 changes: 983 additions & 65 deletions android-godeye-monitor-dashboard/src/MockData.js

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions android-godeye-monitor-dashboard/src/libs/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ class Util {
return new Date(timeMillis).toLocaleTimeString();
}

static getDetailDate(timeMillis) {
return `${new Date(timeMillis).toLocaleTimeString()}.${Math.floor(timeMillis % 1000)}`;
}

/**
* @param methodInfo
* @returns {*}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class MethodCanaryThread extends Component {
if (e.methodEvent) {
s += "cost " + Util.getFormatDuration(e.methodEvent.endMillis - e.methodEvent.startMillis) + '<br/>';
s += e.methodEvent.className + "." + e.methodEvent.methodName + '<br/>';
s += 'From ' + Util.getFormatMAndSAndMS(e.methodEvent.startMillis) + " to " + Util.getFormatMAndSAndMS(e.methodEvent.endMillis);
s += 'From ' + Util.getDetailDate(e.methodEvent.startMillis) + " to " + Util.getDetailDate(e.methodEvent.endMillis);
}
return s;
}
Expand Down Expand Up @@ -281,8 +281,8 @@ class MethodCanaryThread extends Component {
if (this.state.endMillis !== 0 || this.state.startMillis !== 0) {
return <span>Selected duration:&nbsp;
<strong>{Util.getFormatDuration(this.state.endMillis - this.state.startMillis)}</strong>
,&nbsp;Range from&nbsp;<strong>{Util.getFormatMAndSAndMS(this.state.startMillis)}</strong>
&nbsp;to&nbsp;<strong>{Util.getFormatMAndSAndMS(this.state.endMillis)}</strong></span>
,&nbsp;Range from&nbsp;<strong>{Util.getDetailDate(this.state.startMillis)}</strong>
&nbsp;to&nbsp;<strong>{Util.getDetailDate(this.state.endMillis)}</strong></span>
} else {
return <span>Empty...</span>
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,63 @@
/* eslint-disable react/no-string-refs */
/* eslint-disable react/prop-types */
import React, { Component } from 'react';
import React, {Component} from 'react';
import '../App.css';
import Util from "../libs/util";

import { Tree, Popover } from 'antd'
import {Tree, Popover} from 'antd'

class MethodCanaryThreadTree extends Component {

static getMethodValueWithRange(realValue, range) {
return realValue === 0 ? range : realValue;
}

static buildTree(originStart, originEnd, startMillis, endMillis, methodInfos, parent, added, treeData) {
static inWhichParentItem(methodInfo, parentMethodInfos) {
for (let i = 0; i < parentMethodInfos.length; i += 1) {
const item = parentMethodInfos[i];
if (methodInfo.startMillis >= item.startMillis && methodInfo.endMillis <= item.endMillis) {
return item
}
}
return null;
}

/**
* method out of range totally
* @param methodInfo
* @param startMillis
* @param endMillis
*/
static isMethodOutOfRange(methodInfo, startMillis, endMillis) {
return methodInfo.startMillis > endMillis || methodInfo.endMillis < startMillis;
}


static buildTree(methodInfos, startMillis, endMillis) {
let treeData = [];
let currentStack = 0;
let parentList = [];
let currentList = [];
for (let i = 0; i < methodInfos.length; i += 1) {
const item = methodInfos[i];
if (!added.has(item) && (item.endMillis >= startMillis && item.startMillis <= endMillis)) {
if (parent) {
if (!parent.children) {
parent.children = [];
}
parent.children.push(item);
} else {
treeData.push(item);
}
added.add(item);
this.buildTree(originStart, originEnd,
item.startMillis > originStart ? item.startMillis : originStart, item.endMillis < originEnd ? item.endMillis : originEnd,
methodInfos, item, added, treeData);
if (MethodCanaryThreadTree.isMethodOutOfRange(item, startMillis, endMillis)) {
continue;
}
if (item.stack === 0) {
treeData.push(item)
}
if (item.stack > currentStack) {
currentStack = item.stack;
parentList = currentList;
currentList = [];
}
currentList.push(item);
const parent = MethodCanaryThreadTree.inWhichParentItem(item, parentList);
if (parent) {
parent.children.push(item);
}
}
return treeData
}

static cloneMethodCanaryMethodInfo(methodInfo) {
Expand Down Expand Up @@ -57,7 +85,7 @@ class MethodCanaryThreadTree extends Component {
super(props);
this.renderTreeNodes = this.renderTreeNodes.bind(this);
this.getRenderNodeText = this.getRenderNodeText.bind(this);
this.getNodeDetailContent = this.getNodeDetailContent.bind(this);
MethodCanaryThreadTree.getNodeDetailContent = MethodCanaryThreadTree.getNodeDetailContent.bind(this);
this.clear = this.clear.bind(this);
this.refresh = this.refresh.bind(this);
this.state = {
Expand All @@ -84,34 +112,33 @@ class MethodCanaryThreadTree extends Component {
}

refresh(startMillis, endMillis, methodInfos) {
const treeData = [];
const cloned = MethodCanaryThreadTree.cloneMethodCanaryMethodInfos(methodInfos);
cloned.sort((a, b) => {
if (a.stack === b.stack) {
return a.startMillis - b.startMillis;
}
return a.stack - b.stack;
});
MethodCanaryThreadTree.buildTree(startMillis, endMillis, startMillis, endMillis, cloned, null, new Set(), treeData);
this.setState({ treeData, startMillis, endMillis })
const treeData = MethodCanaryThreadTree.buildTree(cloned, startMillis, endMillis);
this.setState({treeData, startMillis, endMillis})
}

getNodeDetailContent(item) {
static getNodeDetailContent(item) {
return (<span>
Real cost {Util.getFormatDuration(item.endMillis - item.startMillis)}<br />
{item.className + "." + item.methodName}<br />
From {Util.getFormatDuration(item.startMillis)} to {Util.getFormatDuration(item.endMillis)}
From {Util.getDetailDate(item.startMillis)} to {Util.getDetailDate(item.endMillis)}
</span>)
}

getRenderNodeText(item) {
const content = this.getNodeDetailContent(item)
const content = MethodCanaryThreadTree.getNodeDetailContent(item);
return <Popover content={content}>
<span>
[Cost and weight]&nbsp;
<strong>{Util.getFormatDuration((this.getMethodEndInRange(item.endMillis) - this.getMethodStartInRange(item.startMillis)))}</strong>
<strong>{Util.getFormatDuration((this.getMethodEndInRange(item.endMillis) - this.getMethodStartInRange(item.startMillis)))}</strong>
&nbsp;
<strong>{((this.getMethodEndInRange(item.endMillis) - this.getMethodStartInRange(item.startMillis)) * 100 / (this.state.endMillis - this.state.startMillis)).toFixed(1) + "%"}</strong>
<strong>{((this.getMethodEndInRange(item.endMillis) - this.getMethodStartInRange(item.startMillis)) * 100 / (this.state.endMillis - this.state.startMillis)).toFixed(1) + "%"}</strong>
&nbsp;&nbsp;
[Method]&nbsp;
<strong>{item.className.substring(item.className.lastIndexOf("/") + 1) + "." + item.methodName}</strong>
Expand All @@ -125,17 +152,17 @@ class MethodCanaryThreadTree extends Component {
<Tree.TreeNode title={
this.getRenderNodeText(item)
}
selectable={false}
key={`${item.stack}#${item.startMillis}#${item.endMillis}`}
dataRef={item}>
selectable={false}
key={`${item.stack}#${item.startMillis}#${item.endMillis}`}
dataRef={item}>
{this.renderTreeNodes(item.children)}
</Tree.TreeNode>
);
}
return <Tree.TreeNode {...item} title={
this.getRenderNodeText(item)
} selectable={false}
key={`${item.stack}#${item.startMillis}#${item.endMillis}`} dataRef={item} isLeaf />;
key={`${item.stack}#${item.startMillis}#${item.endMillis}`} dataRef={item} isLeaf/>;
});

render() {
Expand Down
37 changes: 22 additions & 15 deletions android-godeye-monitor-dashboard/src/pageload/pageload.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { Component } from 'react';
import React, {Component} from 'react';
import '../App.css';

import { Card, Badge, Button, Tag, Input } from 'antd'
import {Card, Badge, Button, Tag, Input} from 'antd'
import Util from "../libs/util";

/**
Expand Down Expand Up @@ -53,7 +53,7 @@ class Pageload extends Component {
this.setState(function (prevState, props) {
const allPageLifecycleProcessedEvents = prevState.allPageLifecycleProcessedEvents;
allPageLifecycleProcessedEvents.unshift(pageLifecycleProcessedEvent);
return { allPageLifecycleProcessedEvents: allPageLifecycleProcessedEvents };
return {allPageLifecycleProcessedEvents: allPageLifecycleProcessedEvents};
});
}

Expand All @@ -65,26 +65,33 @@ class Pageload extends Component {

renderItem(event, key) {
return (
<Card style={{ margin: 4 }} size="small" key={key}>
<Card style={{margin: 4}} size="small" key={key}>
<Badge
color={Util.getGreen()} /><span>{`${new Date(event.startTimeMillis).toLocaleString()}.${event.startTimeMillis % 1000}`}</span>
color={Util.getGreen()}/><span>{`${new Date(event.startTimeMillis).toLocaleString()}.${event.startTimeMillis % 1000}`}</span>
<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;
<strong>{`${event.pageClassName}`}</strong>{`@${event.pageHashCode}`}</span>
<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;
<Tag color={"ACTIVITY" === event.pageType ? "cyan" : "green"}>{event.pageType}</Tag>
<Tag color={('ON_LOAD' === event.lifecycleEvent || 'ON_DRAW' === event.lifecycleEvent) ? "red" : "orange"}>{event.lifecycleEvent}</Tag>
<Tag
color={('ON_LOAD' === event.lifecycleEvent || 'ON_DRAW' === event.lifecycleEvent) ? "red" : "orange"}>{event.lifecycleEvent}</Tag>
{(() => {
if (event.lifecycleEvent === 'ON_LOAD') {
return <span>Cost <strong
style={(event.processedInfo['loadTime'] > Pageload.BAD_LOAD_TIME) ? { color: Util.getRed() } : { color: Util.getGreen() }}>{event.processedInfo['loadTime']}</strong> ms</span>
if (event.processedInfo['loadTime'] > 0) {
return <span>Cost <strong
style={(event.processedInfo['loadTime'] > Pageload.BAD_LOAD_TIME) ? {color: Util.getRed()} : {color: Util.getGreen()}}>{event.processedInfo['loadTime']}</strong> ms</span>
}
} else if (event.lifecycleEvent === 'ON_DRAW') {
return <span>Cost <strong
style={(event.processedInfo['drawTime'] > Pageload.BAD_DRAW_TIME) ? { color: Util.getRed() } : { color: Util.getGreen() }}>{event.processedInfo['drawTime']}</strong> ms</span>
if (event.processedInfo['drawTime'] > 0) {
return <span>Cost <strong
style={(event.processedInfo['drawTime'] > Pageload.BAD_DRAW_TIME) ? {color: Util.getRed()} : {color: Util.getGreen()}}>{event.processedInfo['drawTime']}</strong> ms</span>
}
} else {
return <span>Cost <strong
style={((event.endTimeMillis - event.startTimeMillis) > Pageload.BAD_LIFECYCLE_TIME) ? { color: Util.getRed() } : { color: Util.getGreen() }}>{(event.endTimeMillis - event.startTimeMillis)}</strong> ms</span>
if ((event.endTimeMillis - event.startTimeMillis) > 0) {
return <span>Cost <strong
style={((event.endTimeMillis - event.startTimeMillis) > Pageload.BAD_LIFECYCLE_TIME) ? {color: Util.getRed()} : {color: Util.getGreen()}}>{(event.endTimeMillis - event.startTimeMillis)}</strong> ms</span>
}
}
})()}
</span>
Expand All @@ -107,9 +114,9 @@ class Pageload extends Component {
renderExtra() {
return (<span>
<Input.Search
style={{ width: 200 }}
style={{width: 200}}
placeholder="Input search text"
onSearch={value => this.setState({ searchText: value })}
onSearch={value => this.setState({searchText: value})}
/>
&nbsp;&nbsp;
<Button
Expand All @@ -121,7 +128,7 @@ class Pageload extends Component {
render() {
return (
<Card title="Page Lifecycle(页面生命周期)" extra={this.renderExtra()}>
<div style={{ height: 600, overflow: 'auto' }}>
<div style={{height: 600, overflow: 'auto'}}>
{this.renderTimelines()}
</div>
</Card>);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"main.css": "static/css/main.187d6dcc.css",
"main.css.map": "static/css/main.187d6dcc.css.map",
"main.js": "static/js/main.fc4c522a.js",
"main.js.map": "static/js/main.fc4c522a.js.map"
"main.js": "static/js/main.d9471d24.js",
"main.js.map": "static/js/main.d9471d24.js.map"
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="manifest" href="/manifest.json"><link rel="shortcut icon" href="/favicon.ico"><title>AndroidGodEye</title><link href="/static/css/main.187d6dcc.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script type="text/javascript" src="/static/js/main.fc4c522a.js"></script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="manifest" href="/manifest.json"><link rel="shortcut icon" href="/favicon.ico"><title>AndroidGodEye</title><link href="/static/css/main.187d6dcc.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script type="text/javascript" src="/static/js/main.d9471d24.js"></script></body></html>
Loading

0 comments on commit c404dee

Please sign in to comment.