基于MapReduce的配置型日志分析組件
Author:放翁(文初)
Email:fangweng@taobao.com
Blog: http://blog.csdn.net/cenwenchu79/
目錄
需求場景
組件功能設計關鍵點
設計點分析
分析模型抽象
分析實體抽象:
分析流程抽象:
關鍵路徑任務分割
分析過程生命周期定義:
基于命令行方式執行階段性任務
單任務并行處理化
低耦合多機協作
需求場景
從海量的訪問日志中分析得到系統健康情況,業務增長趨勢。
組件功能設計關鍵點

圖1 組件功能設計點描述圖
這個組件與傳統的MapReduce框架(例如Hadoop)的不同之處在于:
1. 解決問題域側重于日志分析統計及趨勢對比。通過抽象分析對象,分析流程,分析結果定制了配置模型和規則解析處理引擎,實現配置替代編碼實現自定義分析。
2. 對于多機協作采用松散方式,簡化多機協作控制流程。
設計點分析
分析模型抽象
分析模型抽象主要分為兩部分:分析模型抽象和分析流程抽象。分析模型抽象就是將MapReduce的Key-Value統計,轉化成為傳統意義上的報表結構。
分析的輸入:
c1,c2,c3,c4,c5,c6…(通常情況下就是用一定的分割符與內容組合起來的字符串)
MapReduce可以處理的:

如下圖,傳統報表的一行可以看作是多個相同key但不同統計字段組合的結果。

例如:輸入的數據結構如下:
服務名稱,服務類型,服務上行數據流量,服務處理結果(錯誤碼),服務耗時
那么定制如下MapReduce組合:
Key:服務名稱,Value:服務上行數據流量總和。
Key:服務名稱,Value:服務耗時總和。
Key:服務名稱,Value:服務平均耗時。
Key:服務名稱,Value:服務最大耗時。
Key:服務名稱,Value:服務最小耗時。
那么將這些MapReduce處理后的Key-value在組合一次就可以得到:
Key:服務名稱,Value:服務上行數據流量總和,服務耗時總和,服務平均耗時,服務最大耗時,服務最小耗時。
可以看出,現在就已經成為了我們傳統意義上的報表結構。
分析實體抽象:

圖2 實體抽象類圖
Alias對象
對Key和Value生成時需要指定是對那一列或者幾列作分析,因此需要直接指定列號,但是當日志數據結構改變以后,那么就會影響所有的配置,為了便于使用和維護,設定了Alias來規避直接使用列號,具體的使用可以參看最后的配置說明。
ReportEntry對象
MapReduce的Key-Value處理列和規則的定義。
keys表示生成key的列(可以直接使用行號或者使用Alias),Map就是通過對keys的定義將key的列用特定的分割符串聯起來形成新的key串,然后根據后面valueExpression的表達式獲得value(表達式支持通過對列的簡單(+-*/)的計算,也支持對于其他Reportentry的計算獲得value)。
valueExpression是Recude的簡單定義。當前抽象ReportEntryValueType定義的那些類型:min(取最小),max(取最大),sum(總和),average(平均),count(總次數),plain(無需處理,這主要用于顯示key那些列)。具體使用參看后面的配置說明。
conditions可以過濾不符合規則的輸入。(支持簡單的條件表達式組合)
valueFilter可以過濾計算后不符合定義的結果。(支持簡單的條件表達式組合)
MapClass,MapParams,ReduceClass,ReduceParams是用于如果滿足不了現有規則的情況下自定義Map,Reduce,需要實現對應的接口IReportMap或者IReportReduce。
Format可以對最后的結果在輸出的時候格式化一下,當前只支持小數點round。
Report對象
包含了一個和多個ReportEntry對象,同時也支持在Report中定義ReportEntry對象(區別在于是否需要將這個ReportEntry共享給其他Report)。file指定了將會輸出的文件名稱。
Report Alert對象
報表的結果是一天的數據,只能做一些縱向比較,如果需要對多天的數據作橫向比較以及趨勢分析,就需要將多天的報表結合起來分析。具體配置也參見后面的數據定義。
分析流程抽象:
分析流程如下:

圖3 分析流程抽象
流程中可以擴展的在第三步和第四步,第三步影響了Key的生成(當簡單的列組合成字符串無法滿足生成key的情況下可擴展),第四步影響value的生成。(當map的value生成以及Reduce無法滿足需求的情況下可擴展),要使用min,max…以外的reduce,可以直接在ReduceClass中作處理,然后使用plain輸出實現。
這種流程比傳統的MapReduce的寫法好處在于可以對輸入只讀取一次(海量的日志文件為了多種條件分析,反復讀取本身就是最大的損耗)。可以看到在文件IO操作上,不會隨著分析模型配置的增多而增長,中間數據也不會隨著報表組合的不同而過快膨脹(只要報表復用Entry足夠多)。
關鍵路徑任務分割
分析過程生命周期定義:

圖4 分析過程生命周期定義
各階段設計描述:(這些階段都是接口的方法定義)
配置解析:運行期載入,支持在線配置更新,提高系統靈活性。(本地或者URL資源)
獲取分析列表:獲取要分析的文件列表,并根據本地已有數據現狀,選擇性的生成需要獲取的文件數據。
獲取任務數據:從外部文件系統或者數據庫獲得數據。
切割任務數據文件:根據配置的文件塊大小,將任務文件切割到合適的塊。當前實現了實際切割和虛擬切割。TIPS:切割工作可以是并行多線程實現,實際切割是消耗CPU和內存的,特別是使用管道的方式,因此需要評估資源情況來開線程。虛擬切割,只是建立虛擬文件,定義好對應到實體文件的塊起始。前者切割時候消耗較大,執行分析時分析線程干擾較小效率高,后者切割時無太大消耗,執行分析時會有干擾效率不是很高。(這個原因還沒有細查,測試效果是這樣)
分派任務并執行:單機多線程或者多機并行執行分析流程。由于單機會受到CPU和IO的限制,當到達一定數量線程以后,分析效率反而降低,因此才會有分布式的需求。
增量合并處理結果:分派好任務以后,多線程或者多機并性分析時,可以根據執行的情況部分增量式合并處理結果,當所有任務完成以后,結果合并結束。
輸出分析結果:可以根據需求來創建報表格式。當前采用了csv的文件格式來創建報表,易于閱讀和使用。同時也作了入庫處理,也可以直接用Google Chart API創建圖形化的Html。
輸出對比告警:支持當日閥值預警,當日與昨日,當日與上周同期,當日與上月同期數據橫向對比,到達閥值生成預警頁面。
基于命令行方式執行階段性任務
由于整個分析流程已經是任務化了,因此應用只需要具備命令接收功能就可以從任何一步開始執行分析流程,也可以選擇執行到任何步驟直接返回或者輸出中間結果。
當前應用啟動通過監聽端口數據包,接收命令并執行。
單任務并行處理化
希望通過并行化處理來提高效率,就必須要分析場景。
以下情況不適于用并行化執行來提高效率:
1. 串行化任務。(上一個任務的輸出成為下一個任務的輸入,或者是有任務順序的限制)
2. 執行任務時有共享資源競爭。例如CPU,IO,網絡等等,不是并行數越大越好,關鍵還是要看資源分配狀況以及競爭狀況。
3. 并行化開銷大于帶來的收益。應用復雜度(并發控制),并行本身需要的資源消耗(計算能力,空間存儲,帶寬消耗等)較大。(在MapReduce中涉及到一點就是計算代價總是小于數據傳輸,因此讓數據靠近計算,也就能極大提高效率,反過來看,如果為了分布式而將數據遠離于計算,就得不償失了)
4. 流程瓶頸不在于當前并行處理的任務。也就是關鍵路徑的問題。
在分析流程上,對于文件獲取,文件切割,任務分析都是可以做并行化處理,但是還是要根據以上不適合的情況來考慮并行的規模和單機多線程或者多機多線程的方式來做,提升效率。
低耦合多機協作

圖5 兩種Master-Slave模式
上圖畫了兩種Master-Slave模式,看起來沒什么區別,但是箭頭的方向不同帶來的協作模式也有很大的區別。Hadoop Master負責維護任務的分派,任務執行監控,任務合并指派和監控的工作,而松散的M-S模式,Master處于被動狀態,Master的設計更加簡單化同時也增加了處理的靈活度。
用一種形象的描述來說明松散方式下的Master-Slave的協作模式。(就拿年底買火車票來說事)
1. Master要買去成都,武漢,長沙,北京,西安,廣州的火車票各10張。(get Jobs)
2. SlaveA聯系上Master要求領取任務,Master將買成都的火車票任務交給SlaveA,將任務標示為正在執行。(require job)
3. SlaveA自己托關系去開始買票。(do job)
4. SlaveB聯系上Master要求領取任務,Master將買武漢的火車票任務交給SlaveB,將任務標示為正在執行。
5. SlaveB自己托關系開始買票。
6. ……
7. Master發現SlaveA在預期時間內還沒有返回,將任務重置為未分配,允許其他Slave來獲取任務。
8. SlaveB將買到的票給Master,Master將任務標示為完成,并且與其它已經完成的任務統計合并。
9. SlaveA返回,但是發現任務已經被別人完成,則無功而回。(計算資源被浪費)
10. Master發現所有任務已經完成,則向上級匯報,本次任務已經全部完成,輸出結果。
其實從上面的描述可以看到Master設計十分簡單,Slave功能也十分單一,帶來的優勢就是處理簡單,易與管理,同時任何時候都允許新的Slave加入,充分利用資源。缺點就是可能在某些Slave不正常的時候不知情(浪費了部分時間),不過由于Master會有預期結果返回時間,因此這個時間設置小一些會減少浪費時間的場景,但也可能帶來重復勞動的代價,這里可以通過算法來最大程度降低異常節點時間消耗,增加Slave有效工作。
Master職責:獲取任務列表,分派任務,維護任務列表,合并分析結果,出最終結果報表。
Slave職責:請求任務,執行任務,返回分析結果。
下面兩個圖描述了具體的多機協作流程和任務狀態轉換情況。

圖6 多機協作基本流程圖

圖7 任務狀態轉換圖
附錄
項目結構說明:

圖8 項目包圖
com.taobao.top.analysis:單機版和多機版的運行實例類在此包內。
com.taobao.top.analysis.data:抽象配置對象定義。
com.taobao.top.analysis.jobmanager:流程抽象接口和實現。
com.taobao.top.analysis.transport:NIO的底層通信實現。
com.taobao.top.analysis.map:Map接口定義和范例實現。
com.taobao.top.analysis.reduce:Reduce接口定義和范例實現。
com.taobao.top.analysis.util:工具類包。
com.taobao.top.analysis.worker:并行處理的工作者線程實現。
具體配置及說明:
top-report.xml
<?xml version="1.0" encoding="UTF-8"?>
<top_reports>
<!-- 全局條件自動會應用到所有的entity中,
具體condition的定義和使用方式參看后面entity中condition的定義 -->
<global-condition value="$logflag$!=session"/>
<global-condition value="$RECORD_LENGTH$>16&$RECORD_LENGTH$<26"/>
<!-- 全局條件自動會應用到所有的entity中,
具體valuefilter的定義和使用方式參看后面entity中valuefilter的定義
<global-valuefilter value=""/>
-->
<!-- 別名,用于定義分析文件中的列,
防止因為列的移位導致整個報表都需要修改,多個別名可以對應一個列,key代表列數值 -->
<aliases>
<alias name="logflag" key="1"/>
<alias name="remoteIp" key="1"/>
<alias name="partnerId" key="2"/>
<alias name="format" key="3"/>
<alias name="appKey" key="4"/>
<alias name="apiName" key="5"/>
<alias name="readBytes" key="6"/>
<alias name="errorCode" key="7"/>
<alias name="subErrorCode" key="8"/>
<alias name="localIp" key="9"/>
<alias name="nick" key="10"/>
<alias name="version" key="11"/>
<alias name="signMethod" key="12"/>
<alias name="timestamp1" key="13"/>
<alias name="timestamp2" key="14"/>
<alias name="timestamp3" key="15"/>
<alias name="timestamp4" key="16"/>
<alias name="timestamp5" key="17"/>
<alias name="timestamp6" key="18"/>
<alias name="timestamp7" key="19"/>
<alias name="timestamp8" key="20"/>
<alias name="timestamp9" key="21"/>
<alias name="timestamp10" key="22"/>
<alias name="timestamp11" key="23"/>
<alias name="timestamp12" key="24"/>
<alias name="timestamp13" key="25"/>
</aliases>
<!-- 統計列的定義:
id是唯一索引,
name表示在報表中顯示的名稱,
key可以是alias也可以直接定義列號(不推薦)主要表示對那一列或者幾列作為主鍵進行統計例如key=apiname表示對apiName作分類統計,
相同的apiname的紀錄作為一組作后面value的運算,key有保留字GLOBAL_KEY代表對所有記錄作總計統計
value表示計算方式當前支持:min,max,average,count,sum,plain。分別代表統計最小值,最大值,平均值,計數,總和。plain表示直接顯示,一般用于主鍵列的顯示
同時min,max,average,sum,plain支持表達式,用$$圍起來的代表列,entry()表示對統計后的entry作再次計算得到新的entry的結果。
condition表示key的過濾條件,支持對列的過濾條件,支持大于,小于,不等于,大于等于,小于等于的表達式(大于小于需要轉義),
同時可以多個條件串聯用&串聯。注意,表達式中不支持有空格。
valuefilter表示value的過濾條件,支持計算出來的結果過濾,有大于,小于,不等于,大于等于,小于等于,是否是數字(isnumber),大于小于需要轉義,
同時可以多個條件串聯用&串聯。注意,表達式中不支持有空格。
支持自定義map和reduce函數:范例如下:
mapClass="com.taobao.top.analysis.map.TimeMap" mapParams="xxx=xxx"
reduceClass="com.taobao.top.analysis.reduce.TimeReduce" reduceParams="xxx=xxx"
-->
<entrys>
<ReportEntry id="1" name="服務請求總次數" key="apiName" value="count()"/>
<ReportEntry id="2" name="訪問成功次數" key="apiName" value="count()" condition="$errorCode$=0" />
<ReportEntry id="3" name="訪問失敗次數" key="apiName" value="count()" condition="$errorCode$!=0" />
<ReportEntry id="4" name="業務平均處理時間" key="apiName" value="average($timestamp4$ - $timestamp3$)" valuefilter=">=0&<10000&isnumber&round:3"/>
<ReportEntry id="5" name="TOP平均處理時間" key="apiName" value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)" valuefilter=">=0&<10000&isnumber&round:3"/>
<ReportEntry id="6" name="業務處理最小時間" key="apiName" value="min($timestamp4$ - $timestamp3$)" valuefilter=">=0&isnumber"/>
<ReportEntry id="7" name="業務處理最大時間" key="apiName" value="max($timestamp4$ - $timestamp3$)" valuefilter=">=0&<10000&isnumber"/>
<ReportEntry id="8" name="TIP服務調用前處理時間" key="apiName" value="average($timestamp3$ - $timestamp1$)" valuefilter=">=0&<10000&isnumber&round:3"/>
<ReportEntry id="9" name="TIP服務調用后處理時間" key="apiName" value="average($timestamp5$ - $timestamp4$)" valuefilter=">=0&<10000&isnumber&round:3"/>
<ReportEntry id="10" name="日志及輸出消耗時間" key="apiName" value="average($timestamp6$ - $timestamp5$)" valuefilter=">=0&<10000&isnumber&round:3"/>
<ReportEntry id="api_AverageSuccessTIPTimeConsume" name="成功請求TOP處理平均時間" key="apiName" condition="$errorCode$=0"
value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)" valuefilter=">=0&isnumber&round:3"/>
<ReportEntry id="api_AverageFailTIPTimeConsume" name="失敗請求TOP處理平均時間" key="apiName" condition="$errorCode$!=0"
value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)" valuefilter=">=0&isnumber&round:3"/>
<ReportEntry id="11" name="訪問總數" key="GLOBAL_KEY" value="count()" />
<ReportEntry id="12" name="成功總數" key="GLOBAL_KEY" value="count()" condition="$errorCode$=0" />
<ReportEntry id="13" name="失敗總數" key="GLOBAL_KEY" value="count()" condition="$errorCode$!=0" />
<ReportEntry id="14" name="業務平均消耗時間(ms)" key="GLOBAL_KEY" value="average($timestamp4$ - $timestamp3$)" valuefilter=">=0&<10000&isnumber&round:3"/>
<ReportEntry id="15" name="TOP平均消耗時間(ms)" key="GLOBAL_KEY" value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)" valuefilter=">=0&<10000&isnumber&round:3"/>
<ReportEntry id="16" name="錯誤次數" key="errorCode" value="count()" condition="$errorCode$!=0" />
<ReportEntry id="17" name="單機訪問總量" key="localIp" value="count()" />
<ReportEntry id="18" name="單機訪問成功量" key="localIp" value="count()" condition="$errorCode$=0" />
<ReportEntry id="19" name="單機訪問失敗量" key="localIp" value="count()" condition="$errorCode$!=0" />
<ReportEntry id="20" name="單機業務平均消耗時間(ms)" key="localIp" value="average($timestamp4$ - $timestamp3$)" valuefilter=">=0&<10000&isnumber&round:3"/>
<ReportEntry id="21" name="單機TOP平均消耗時間(ms)" key="localIp" value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)" valuefilter=">=0&<10000&isnumber&round:3"/>
<ReportEntry id="22" name="應用訪問總量" key="appKey" value="count()" />
<ReportEntry id="23" name="應用成功訪問總量" key="appKey" value="count()" condition="$errorCode$=0" />
<ReportEntry id="24" name="應用失敗訪問總量" key="appKey" value="count()" condition="$errorCode$!=0"/>
<ReportEntry id="25" name="應用訪問業務平均耗時(ms)" key="appKey" value="average($timestamp4$ - $timestamp3$)" valuefilter=">=0&<10000&isnumber&round:3"/>
<ReportEntry id="26" name="應用訪問TOP平均耗時(ms)" key="appKey" value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)" valuefilter=">=0&<10000&isnumber&round:3"/>
<ReportEntry id="27" name="時間段內訪問總量" key="timestamp1" value="count()"
mapClass="com.taobao.top.analysis.map.TimeMap"/>
<ReportEntry id="28" name="時間段內訪問成功總量" key="timestamp1" value="count()" condition="$errorCode$=0"
mapClass="com.taobao.top.analysis.map.TimeMap"/>
<ReportEntry id="29" name="時間段內訪問失敗總量" key="timestamp1" value="count()" condition="$errorCode$!=0"
mapClass="com.taobao.top.analysis.map.TimeMap" valuefilter=">=0&isnumber&round:3"/>
<ReportEntry id="30" name="時間段內訪問業務平均耗時(ms)" key="timestamp1" value="average($timestamp4$ - $timestamp3$)"
mapClass="com.taobao.top.analysis.map.TimeMap" valuefilter=">=0&isnumber&round:3"/>
<ReportEntry id="31" name="時間段內訪問TOP平均耗時(ms)" key="timestamp1" value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)"
mapClass="com.taobao.top.analysis.map.TimeMap" valuefilter=">=0&isnumber&round:3"/>
<ReportEntry id="api_sysFailCount" name="TOP平臺級錯誤量" key="apiName" value="count()"
condition="$errorCode$<100&$errorCode$>0" />
<ReportEntry id="api_serviceSysFailCount" name="服務系統級錯誤量(900到901)" key="apiName" value="count()"
condition="$errorCode$<902&$errorCode$>899" />
<ReportEntry id="api_serviceSysFailCount1" name="服務系統級錯誤量(大于901)" key="apiName" value="count()"
condition="$errorCode$>901"/>
<ReportEntry id="api_serviceAPIFailCount" name="服務業務級錯誤量" key="apiName" value="count()"
condition="$errorCode$>100&$errorCode$<900"/>
<ReportEntry id="api_serviceSysFailTotalCount" name="服務系統級總錯誤量" key="apiName" value="count()"
condition="$errorCode$>899" />
</entrys>
<!--
報表定義:
id為報表主鍵,除了數字也可以用英文字符串
file為報表保存的名稱,不建議使用中文
entryList描述了報表包含的所有的entry,可以引用上面定義的全局性的entry,也可以內部定義私有的entry。
-->
<reports>
<report id="0" file="totalTIPConsumeReport">
<entryList>
<entry name="TOP獲取參數耗時" key="GLOBAL_KEY" value="average($timestamp7$)" condition="$errorCode$=0"/>
<entry name="TOP獲取參數最小耗時" key="GLOBAL_KEY" value="min($timestamp7$)" condition="$errorCode$=0"/>
<entry name="TOP獲取參數最大耗時" key="GLOBAL_KEY" value="max($timestamp7$)" condition="$errorCode$=0"/>
<entry name="獲取API信息耗時" key="GLOBAL_KEY" value="average($timestamp8$)" condition="$errorCode$=0"/>
<entry name="獲取API信息最小耗時" key="GLOBAL_KEY" value="min($timestamp8$)" condition="$errorCode$=0"/>
<entry name="獲取API信息最大耗時" key="GLOBAL_KEY" value="max($timestamp8$)" condition="$errorCode$=0"/>
<entry name="處理協議必選參數耗時" key="GLOBAL_KEY" value="average($timestamp9$)" condition="$errorCode$=0"/>
<entry name="處理協議必選參數最小耗時" key="GLOBAL_KEY" value="min($timestamp9$)" condition="$errorCode$=0"/>
<entry name="處理協議必選參數最大耗時" key="GLOBAL_KEY" value="max($timestamp9$)" condition="$errorCode$=0"/>
<entry name="頻率黑名單校驗耗時" key="GLOBAL_KEY" value="average($timestamp10$)" condition="$errorCode$=0"/>
<entry name="頻率黑名單校驗最小耗時" key="GLOBAL_KEY" value="min($timestamp10$)" condition="$errorCode$=0"/>
<entry name="頻率黑名單校驗最大耗時" key="GLOBAL_KEY" value="max($timestamp10$)" condition="$errorCode$=0"/>
<entry name="協議可選參數校驗耗時" key="GLOBAL_KEY" value="average($timestamp11$)" condition="$errorCode$=0"/>
<entry name="協議可選參數校驗最小耗時" key="GLOBAL_KEY" value="min($timestamp11$)" condition="$errorCode$=0"/>
<entry name="協議可選參數校驗最大耗時" key="GLOBAL_KEY" value="max($timestamp11$)" condition="$errorCode$=0"/>
<entry name="業務必選參數校驗耗時" key="GLOBAL_KEY" value="average($timestamp12$)" condition="$errorCode$=0"/>
<entry name="業務必選參數校驗最小耗時" key="GLOBAL_KEY" value="min($timestamp12$)" condition="$errorCode$=0"/>
<entry name="業務必選參數校驗最大耗時" key="GLOBAL_KEY" value="max($timestamp12$)" condition="$errorCode$=0"/>
<entry name="業務可選參數校驗耗時" key="GLOBAL_KEY" value="average($timestamp13$)" condition="$errorCode$=0"/>
<entry name="業務可選參數校驗最小耗時" key="GLOBAL_KEY" value="min($timestamp13$)" condition="$errorCode$=0"/>
<entry name="業務可選參數校驗最大耗時" key="GLOBAL_KEY" value="max($timestamp13$)" condition="$errorCode$=0"/>
</entryList>
</report>
<report id="1" file="totalReport">
<entryList>
<entry id="11"/>
<entry name="訪問總流量(M)" key="GLOBAL_KEY" value="sum($readBytes$/#1000000#)" valuefilter=">=0&isnumber&round:4"/>
<entry id="12"/>
<entry name="訪問成功率" key="GLOBAL_KEY" value="plain(entry(12)/entry(11))" valuefilter=">=0&isnumber&round:4"/>
<entry id="13"/>
<entry name="平臺系統錯誤率(占總錯誤百分比)" key="GLOBAL_KEY" value="plain(entry(sysFailCount)/entry(13))" valuefilter=">=0&isnumber&round:4"/>
<entry name="服務系統錯誤率(占總錯誤百分比)" key="GLOBAL_KEY" value="plain(entry(serviceSysFailCount)/entry(13))" valuefilter=">=0&isnumber&round:4"/>
<entry name="服務業務錯誤率(占總錯誤百分比)" key="GLOBAL_KEY" value="plain(entry(serviceAPIFailCount)/entry(13))" valuefilter=">=0&isnumber&round:4"/>
<entry id="14"/>
<entry id="15"/>
<entry name="TOP成功處理平均耗時" key="GLOBAL_KEY"
value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)" condition="$errorCode$=0" valuefilter=">=0&isnumber&round:3"/>
<entry id="sysFailCount" name="平臺系統錯誤數" key="GLOBAL_KEY" value="count()" condition="$errorCode$<100&$errorCode$>0"/>
<entry id="serviceSysFailCount" name="服務系統錯誤數" key="GLOBAL_KEY" value="count()" condition="$errorCode$>899"/>
<entry id="serviceAPIFailCount" name="服務業務錯誤數" key="GLOBAL_KEY" value="count()" condition="$errorCode$>100&$errorCode$<900"/>
</entryList>
</report>
<report id="2" file="apiReport">
<entryList>
<entry name="服務名稱" key="apiName" value="plain($apiName$)" />
<entry id="1"/>
<entry name="占總量比例" key="apiName" value="plain(entry(1)/entry(sum:1))" valuefilter=">=0&isnumber&round:3"/>
<entry id="2"/>
<entry name="服務請求成功率" key="apiName" value="plain(entry(2)/entry(1))" valuefilter=">=0&isnumber&round:3"/>
<entry id="3"/>
<entry id="4"/>
<entry id="5"/>
<entry name="TOP占總處理時間百分比" key="apiName" value="plain(entry(5)/entry(5+4))" valuefilter=">=0&isnumber&round:3"/>
<entry id="api_AverageSuccessTIPTimeConsume"/>
<entry id="api_AverageFailTIPTimeConsume"/>
<entry id="6"/>
<entry id="7"/>
<entry id="8"/>
<entry id="9"/>
<entry id="10"/>
<entry id="api_sysFailCount"/>
<entry id="api_serviceSysFailTotalCount"/>
<entry id="api_serviceAPIFailCount"/>
</entryList>
</report>
<report id="3" file="errorCodeReport">
<entryList>
<entry id="33" name="錯誤碼" key="errorCode" value="plain($errorCode$)" condition="$errorCode$!=0"/>
<entry id="16"/>
<entry name="錯誤比例" key="errorCode" value="plain(entry(16)/entry(sum:16))" condition="$errorCode$!=0" valuefilter=">=0&isnumber&round:3"/>
</entryList>
</report>
<report id="4" file="machineReport">
<entryList>
<entry name="服務器IP" key="localIp" value="plain($localIp$)" />
<entry id="17"/>
<entry name="占總量比例" key="localIp" value="plain(entry(17)/entry(sum:17))" valuefilter=">=0&isnumber&round:3"/>
<entry id="18"/>
<entry name="成功率" key="localIp" value="plain(entry(18)/entry(17))" valuefilter=">=0&isnumber&round:3"/>
<entry id="19"/>
<entry id="20"/>
<entry id="21"/>
<entry name="TOP占總處理時間比值" key="localIp" value="plain(entry(21)/entry(20+21))" valuefilter=">=0&isnumber&round:3"/>
</entryList>
</report>
<report id="5" file="appReport">
<entryList>
<entry name="應用ID" key="appKey" value="plain($appKey$)" />
<entry id="22"/>
<entry name="占總訪問比例" key="appKey" value="plain(entry(22)/entry(sum:22))" valuefilter=">=0&isnumber&round:3"/>
<entry id="23"/>
<entry name="應用訪問成功率" key="appKey" value="plain(entry(23)/entry(22))" valuefilter=">=0&isnumber&round:3"/>
<entry id="24"/>
<entry id="25"/>
<entry id="26"/>
</entryList>
</report>
<report id="6" file="periodReport">
<entryList>
<entry name="時間段" key="timestamp1" value="plain($timestamp1$)"
mapClass="com.taobao.top.analysis.map.TimeMap"
reduceClass="com.taobao.top.analysis.reduce.TimeReduce"/>
<entry id="27"/>
<entry name="占請求總量比例" key="timestamp1" value="plain(entry(27)/entry(sum:27))" valuefilter=">=0&isnumber&round:3"/>
<entry id="28"/>
<entry name="請求成功率" key="timestamp1" value="plain(entry(28)/entry(27))" valuefilter=">=0&isnumber&round:3"/>
<entry id="29"/>
<entry id="30"/>
<entry id="31"/>
</entryList>
</report>
<report id="7" file="appAPIReport">
<entryList>
<entry name="應用ID" key="appKey,apiName" value="plain($appKey$)" condition="$errorCode$=0"/>
<entry name="服務名稱" key="appKey,apiName" value="plain($apiName$)" condition="$errorCode$=0"/>
<entry id="app_api_successCount" name="訪問成功總量" key="appKey,apiName" value="count()" condition="$errorCode$=0"/>
</entryList>
</report>
<report id="8" file="errorCodeAndSubErrorCodeReport">
<entryList>
<entry name="錯誤碼" key="errorCode,subErrorCode" value="plain($errorCode$)" condition="$errorCode$!=0"/>
<entry name="子錯誤碼" key="errorCode,subErrorCode" value="plain($subErrorCode$)" condition="$errorCode$!=0"/>
<entry name="錯誤總數" key="errorCode,subErrorCode" value="count()" condition="$errorCode$!=0"/>
</entryList>
</report>
<report id="9" file="apiFailDetailReport">
<entryList>
<entry name="服務名稱" key="apiName" value="plain($apiName$)" />
<entry id="1"/>
<entry id="3"/>
<entry name="失敗數占服務請求量比例" key="apiName" value="plain(entry(3)/entry(1))" valuefilter=">=0&isnumber&round:3"/>
<entry name="失敗數占失敗總量比例" key="apiName" value="plain(entry(3)/entry(sum:3))" valuefilter=">=0&isnumber&round:3"/>
<entry id="api_sysFailCount"/>
<entry name="平臺級錯誤占總服務請求比例" key="apiName" value="plain(entry(api_sysFailCount)/entry(1))" valuefilter=">=0&isnumber&round:3"/>
<entry id="api_serviceSysFailCount"/>
<entry name="服務系統級錯誤量(900到901)占總服務請求比例" key="apiName" value="plain(entry(api_serviceSysFailCount)/entry(1))" valuefilter=">=0&isnumber&round:3"/>
<entry id="api_serviceSysFailCount1"/>
<entry name="服務系統級錯誤量(大于901)占總服務請求比例" key="apiName" value="plain(entry(api_serviceSysFailCount1)/entry(1))" valuefilter=">=0&isnumber&round:3"/>
<entry id="api_serviceAPIFailCount"/>
<entry name="服務業務級錯誤占總服務請求比例" key="apiName" value="plain(entry(api_serviceAPIFailCount)/entry(1))" valuefilter=">=0&isnumber&round:3"/>
</entryList>
</report>
<report id="10" file="appApiErrorReport">
<entryList>
<entry name="應用ID" key="appKey,apiName,errorCode" value="plain($appKey$)" condition="$errorCode$!=0"/>
<entry name="服務名稱" key="appKey,apiName,errorCode" value="plain($apiName$)" condition="$errorCode$!=0"/>
<entry name="錯誤碼" key="appKey,apiName,errorCode" value="plain($errorCode$)" condition="$errorCode$!=0"/>
<entry name="錯誤次數" key="appKey,apiName,errorCode" value="count()" condition="$errorCode$!=0"/>
</entryList>
</report>
<report id="11" file="verionAndSignTypeReport">
<entryList>
<entry name="版本號" key="version,signMethod" value="plain($version$)" condition="$errorCode$=0"/>
<entry name="簽名類型" key="version,signMethod" value="plain($signMethod$)" condition="$errorCode$=0"/>
<entry name="訪問成功總數" key="version,signMethod" value="count()" condition="$errorCode$=0"/>
</entryList>
</report>
<report id="12" file="appErrorCodeReport">
<entryList>
<entry name="應用ID" key="appKey,errorCode" value="plain($appKey$)" condition="$errorCode$!=0"/>
<entry name="錯誤碼" key="appKey,errorCode" value="plain($errorCode$)" condition="$errorCode$!=0"/>
<entry name="錯誤總數" key="appKey,errorCode" value="count()" condition="$errorCode$!=0"/>
</entryList>
</report>
</reports>
<alerts>
<!-- 對比告警 alerttype:now,day,week,month。
valve代表閥值:<(now類型代表小于告警,如果是同期比較代表下降超過),
>(now類型代表大于告警,如果是同期比較代表上升),沒有符號代表絕對值超過告警-->
<alert reportId="1" entryname="訪問成功率" alerttype="now" valve="<0.9" />
<alert reportId="1" entryname="訪問總數" alerttype="day" valve="5000000" />
<alert reportId="1" entryname="訪問成功率" alerttype="day" valve="<0.01" />
<alert reportId="1" entryname="平臺系統錯誤率" alerttype="day" valve=">0.05" />
<alert reportId="1" entryname="服務系統錯誤率" alerttype="day" valve=">0.05" />
<alert reportId="1" entryname="服務業務錯誤率" alerttype="day" valve=">0.05" />
<alert reportId="1" entryname="TOP平均消耗時間(ms)" alerttype="day" valve=">10" />
<alert reportId="1" entryname="業務平均消耗時間(ms)" alerttype="day" valve=">10" />
<alert reportId="2" keyentry="服務名稱" entryname="占總量比例" alerttype="day" valve=">0.01" />
<alert reportId="2" keyentry="服務名稱" entryname="服務請求成功率" alerttype="day" valve="<0.01" />
<alert reportId="2" keyentry="服務名稱" entryname="業務平均處理時間" alerttype="day" valve=">20" />
<alert reportId="2" keyentry="服務名稱" entryname="TOP平均處理時間" alerttype="day" valve=">20" />
<alert reportId="3" keyentry="錯誤碼" entryname="錯誤比例" alerttype="day" valve=">0.01" />
<alert reportId="4" keyentry="服務器IP" entryname="成功率" alerttype="day" valve="<0.01" />
<alert reportId="5" keyentry="應用ID" entryname="占總訪問比例" alerttype="day" valve="0.01" />
<alert reportId="5" keyentry="應用ID" entryname="應用訪問成功率" alerttype="day" valve="<0.05" />
<alert reportId="7" keyentry="應用ID,服務名稱" entryname="訪問成功總量" alerttype="day" valve=">10000000" />
<alert reportId="9" keyentry="服務名稱" entryname="失敗數占總量比例" alerttype="day" valve=">0.01" />
<alert reportId="10" keyentry="應用ID,服務名稱,錯誤碼" entryname="錯誤次數" alerttype="day" valve=">10000" />
<alert reportId="11" keyentry="版本號,簽名類型" entryname="訪問成功總數" alerttype="day" valve="<1000000" />
<alert reportId="12" keyentry="應用ID,錯誤碼" entryname="錯誤總數" alerttype="day" valve=">100000" />
</alerts>
</top_reports>