Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
AppMonitorSubscriber
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nongyingchen
AppMonitorSubscriber
Commits
a2b1e00c
Commit
a2b1e00c
authored
Apr 30, 2019
by
trace
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add monitor scrip in here
parent
a5b8f720
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
783 additions
and
0 deletions
+783
-0
play.js
+783
-0
No files found.
play.js
0 → 100644
View file @
a2b1e00c
var
gplay
=
require
(
'google-play-scraper'
)
var
nodemailer
=
require
(
'nodemailer'
)
var
fs
=
require
(
'fs'
)
var
username
=
require
(
'os'
).
userInfo
().
username
var
request
=
require
(
'request'
)
var
util
=
require
(
'util'
)
var
getPromiss
=
util
.
promisify
(
request
.
get
)
let
subApi
=
"https://git.starwin.tech/nongyingchen/AppMonitorSubscriber/raw/master/subscriber.json"
log
(
`当前奔跑在:
${
username
}
`
)
let
ding
=
'https://oapi.dingtalk.com/robot/send?access_token='
let
debugDingding
=
`
${
ding
}
bf03c69128b771107b8715911b8a76db61a55cbd8b00e1a2c955578c2a3da719`
let
notifyDingding
=
`
${
ding
}
61403ec65efd7a9e40cb6d490e1bfab8aff28800696918a23ec4dffdf5aa1315`
let
daichao
=
`http://admin.uuang.co.id/admin/loan/listactive?current=0&size=10000&descs%5B0%5D=priority&packageId=10002`
// Config ------------------------------------------------------------
let
sec
=
1000
;
let
minute
=
sec
*
60
let
defaultIntervalTime
=
isTest
()
&&
(
minute
*
1
)
||
(
minute
*
15
)
// 默认间隔15分钟
let
defaultIntervalTimeForOurApp
=
isTest
()
?
0
:
12
// 自有 app 默认时间间隔
let
lastIntervalTime
=
defaultIntervalTime
// 最新获取权限时间间隔
let
sleepTime
=
isTest
()
&&
(
sec
*
2
)
||
(
sec
*
5
)
// 每个请求间隔5秒
let
requestTimeout
=
sec
*
20
let
requestTopAppNum
=
isTest
()
&&
1
||
100
let
aliveTime
=
9
// 多少点后开始发送邮件
let
theDaySendList
=
[
1
,
2
,
3
,
4
,
5
,
6
,
7
]
// 发送列表的时间(周几)
let
aliveInterval
=
isTest
()
&&
0.1
||
3
// 发送邮件间隔时间
let
start
=
true
// 是否开始爬取监控
let
dailyOnlineStartHours
=
7
let
dailyOnlineEndHours
=
9
let
crabName
=
`东南亚现金贷App监控
${
isTest
()
&&
'(Test)'
||
''
}
`
let
monitorRegion
=
{
'vn'
:
'越南'
,
'ph'
:
'菲律宾'
,
'id'
:
'印尼'
}
let
monitorType
=
{
'FINANCE'
:
'财务'
}
let
statusFile
=
`
${
process
.
cwd
()}
/status.json`
let
monitorApps
=
`
${
process
.
cwd
()}
/google-play-monitor-apps.json`
let
base_gp_url
=
'https://play.google.com/store/apps/details?id='
let
developer
=
[
'yingchen.nong@starwin.com'
]
let
notifyEmail
=
developer
let
daichaoApps
=
[]
let
ourAppIds
=
[]
let
ourApps
=
{}
let
hitDaichao
=
isTest
()
?
1
:
0
let
hitOurs
=
isTest
()
?
1
:
0
// 返回需要监控的自有 app
let
isTimeToAppendOurApp
=
(
apps
)
=>
{
// 需求变更, 是首次加入判断超过12小时就监控, 非每次12小时
// 遍历所有自有 app, 看当前时间与加入时间, 超过12小时就加入返回list
let
needMonitorApps
=
[]
for
(
let
i
in
apps
)
{
let
key
=
apps
[
i
]
let
timeIn
=
status
[
key
]
&&
status
[
key
].
timeIn
if
(
!
timeIn
)
{
continue
}
timeIn
=
new
Date
(
timeIn
)
let
date
=
new
Date
()
// 加上初次监控间隔
timeIn
.
setHours
(
timeIn
.
getHours
()
+
defaultIntervalTimeForOurApp
)
if
(
date
>=
timeIn
)
{
log
(
`初次加入监控 ------------>
${
key
}
`
)
needMonitorApps
.
push
(
key
)
}
}
return
needMonitorApps
}
let
allNames
=
names
=>
{
let
an
=
[]
Object
.
keys
(
names
).
forEach
(
key
=>
{
if
(
key
==
"ourApps"
)
{
// 返回需要监控的自有 app
an
=
[...
an
,
...
isTimeToAppendOurApp
(
names
[
key
])]
}
else
{
an
=
[...
an
,
...
names
[
key
]]
}
})
return
Array
.
from
(
new
Set
(
an
))
}
function
log
(
content
)
{
if
(
isTest
())
{
console
.
log
(
`[
${
new
Date
().
toLocaleString
()}
]:
${
content
}
`
)
}
}
function
isTest
()
{
let
testName
=
[
'taketrace'
]
return
testName
.
includes
(
username
)
}
// Code ------------------------------------------------------------
// 状态记录
let
status
=
{}
let
monitorNames
=
{}
let
isFirstRun
=
false
// 获取记录上次状态得文件
try
{
status
=
JSON
.
parse
(
fs
.
readFileSync
(
statusFile
,
'utf-8'
))
isFirstRun
=
false
}
catch
(
err
)
{
isFirstRun
=
true
console
.
log
(
`状态文件不存在, 直接使用空的{}\n
${
err
.
toString
()}
`
)
}
// 获取记录上次更新监控名得文件
try
{
let
fileNames
=
JSON
.
parse
(
fs
.
readFileSync
(
monitorApps
,
'utf-8'
))
if
(
Array
.
isArray
(
fileNames
))
{
monitorNames
[
'vn'
]
=
fileNames
console
.
log
(
'原来只记录数组形式, 现在变更为对象形式, 原数组放到vn数组中'
)
}
else
{
monitorNames
=
fileNames
}
isFirstRun
=
false
}
catch
(
err
)
{
console
.
log
(
`监控列表文件不存在, 直接使用空的{}\n
${
err
.
toString
()}
`
)
}
let
newOnline
=
[]
// 新上架
let
newOffline
=
[]
// 新下架
let
permissionChange
=
{}
// 权限变化
let
failedApps
=
[]
// 获取失败的
let
newTopMonitorNames
=
{}
let
errorLog
=
[]
// 错误记录
log
(
'log 打开'
)
// 开始监控
if
(
isTest
())
{
// sendEmail(`《上3下4T4》【上4下5T8】`, developer)
startMonitor
()
}
else
{
startMonitor
()
}
async
function
startMonitor
()
{
log
(
'开始监控'
)
while
(
start
)
{
log
(
`抓取一圈`
)
await
getConfig
()
.
then
(
getDaichao
)
.
then
(
getTop100
)
.
then
(()
=>
fs
.
writeFileSync
(
monitorApps
,
JSON
.
stringify
(
monitorNames
)))
// 保存到本地
.
then
(()
=>
{
// 动态修改间隔得值
// 自有 app 没到时间不会进入监控
let
allN
=
allNames
(
monitorNames
)
return
allN
})
.
then
(
allN
=>
monitorIfOnline
(
allN
))
.
then
(
genMail
)
.
then
(
sendEmail
)
.
then
(()
=>
{
// 每日在线列表报告
if
(
!
isInTimeInRangeToday
(
dailyOnlineStartHours
,
dailyOnlineEndHours
))
{
log
(
'今天不在时间段或者已发过当日在线 app 列表'
)
return
}
let
onlineApps
=
ourAppIds
.
filter
(
val
=>
status
[
val
]
&&
status
[
val
].
status
||
false
)
let
daichaoOnlines
=
daichaoApps
.
filter
(
val
=>
status
[
val
]
&&
status
[
val
].
status
||
false
)
let
content
=
''
content
+=
wrapSummary
(
`Gitlab 在线 app (
${
onlineApps
.
length
}
/
${
ourAppIds
.
length
}
)`
,
onlineApps
.
map
(
val
=>
link
(
val
)))
content
+=
wrapSummary
(
`贷超在线 App (
${
daichaoOnlines
.
length
}
/
${
daichaoApps
.
length
}
)`
,
daichaoOnlines
.
map
(
val
=>
link
(
val
)))
sendEmail
(
content
)
})
.
then
(()
=>
{
log
(
'成功'
)
// 将status 写入到文件
fs
.
writeFileSync
(
statusFile
,
JSON
.
stringify
(
status
))
log
(
`文件写入成功`
)
})
.
then
(()
=>
log
(
'over'
))
.
catch
(
err
=>
{
lastIntervalTime
=
lastIntervalTime
*
2
let
content
=
`监控出错
${
err
}
\n间隔时间调整为
${(
lastIntervalTime
)
/
minute
}
分钟`
content
+=
markError
()
console
.
log
(
content
)
sendEmail
(
content
,
developer
)
dingDing
(
content
)
if
(
err
.
toString
().
includes
(
'ENOSPC'
))
{
sendEmail
(
`小老弟, 这个爬虫呆着的机器没空间了,
${
err
.
toString
()}
`
,
'chaolun.ni@starwin.com'
)
}
// 出错了需要重新抓, 需要清空之前缓存的状态
newOffline
=
[]
newOnline
=
[]
permissionChange
=
{}
failedApps
=
[]
errorLog
=
[]
newTopMonitorNames
=
{}
hitDaichao
=
0
hitOurs
=
0
})
await
sleepForInterVal
(
lastIntervalTime
)
}
}
async
function
getDaichao
()
{
await
getPromiss
(
daichao
)
.
then
(
val
=>
{
if
(
isTest
())
{
daichaoApps
=
[]
return
}
daichaoData
=
JSON
.
parse
(
val
&&
val
.
body
&&
val
.
body
||
"{}"
).
data
daichaoApps
=
daichaoData
&&
daichaoData
.
map
(
app
=>
app
.
packageName
)
||
[]
log
(
`代超数据:
${
daichaoApps
.
length
}
个`
)
monitorNames
[
"daichao"
]
=
daichaoApps
if
(
daichaoApps
.
length
==
0
)
{
log
(
'代超数据为空'
)
}
})
.
catch
(
err
=>
{
errorLog
.
push
(
`贷超获取失败:
${
err
.
toString
()}
`
)
return
})
}
async
function
getConfig
()
{
await
getPromiss
(
subApi
).
then
(
val
=>
{
log
(
'------------ get congfig from gitlab -----------'
)
log
(
val
.
body
)
let
dataes
=
{}
if
(
isTest
())
{
try
{
dataes
=
JSON
.
parse
(
val
.
body
)
}
catch
(
err
)
{
throw
`哪位老哥, 配置文件写错了啊...>>>>>>>>>\n
${
err
}
\n<<<<<<<<<\n`
}
ourApps
=
dataes
.
ourApps
||
{}
ourAppIds
=
Object
.
keys
(
ourApps
)
if
(
ourAppIds
.
length
==
0
)
{
ourApps
=
{
"com.globe.gcash.android"
:
"测试我的"
}
ourAppIds
=
[
"com.globe.gcash.android"
]
}
monitorNames
[
"ourApps"
]
=
ourAppIds
ourAppIds
.
forEach
(
id
=>
{
// 添加进状态文件, 设置上名字 (因为后面的能知道名字的操作只有获取前100的时候, 获取权限是不知道名字的)
status
[
id
]
=
{...(
status
[
id
]
||
{}),
appName
:
ourApps
[
id
]}
if
(
!
status
[
id
].
timeIn
)
{
// 如果没有记录加入时间, 记录, 加入时间只记录一次, 在 isTimeToAppendOurApp 中判断记录时间, 超过12小时就开始监控
status
[
id
]
=
{
...
status
[
id
],
timeIn
:
Date
()
}
}
})
}
else
{
dataes
=
JSON
.
parse
(
val
.
body
)
let
config
=
dataes
.
config
let
subscriber
=
dataes
.
subscriber
ourApps
=
dataes
.
ourApps
||
{}
ourAppIds
=
Object
.
keys
(
ourApps
)
monitorNames
[
"ourApps"
]
=
ourAppIds
ourAppIds
.
forEach
(
id
=>
{
// 添加进状态文件, 设置上名字 (因为后面的能知道名字的操作只有获取前100的时候, 获取权限是不知道名字的)
status
[
id
]
=
{...(
status
[
id
]
||
{}),
appName
:
ourApps
[
id
]}
if
(
!
status
[
id
].
timeIn
)
{
// 如果没有记录加入时间, 记录, 加入时间只记录一次, 在 isTimeToAppendOurApp 中判断记录时间, 超过12小时就开始监控
status
[
id
]
=
{...
status
[
id
],
timeIn
:
Date
()}
}
})
// 订阅人
notifyEmail
=
subscriber
&&
Object
.
keys
(
subscriber
)
||
notifyEmail
// 配置更新
defaultIntervalTime
=
minute
*
(
config
.
defaultIntervalTime
||
defaultIntervalTime
)
sleepTime
=
sec
*
(
config
.
sleepTime
||
sleepTime
)
requestTimeout
=
sec
*
(
config
.
requestTimeout
||
requestTimeout
)
requestTopAppNum
=
config
.
requestTopAppNum
||
requestTopAppNum
aliveTime
=
config
.
aliveTime
||
aliveTime
if
(
Array
.
isArray
(
config
.
theDaySendList
))
{
theDaySendList
=
config
.
theDaySendList
}
else
{
theDaySendList
=
config
.
theDaySendList
&&
[
config
.
theDaySendList
]
||
theDaySendList
}
aliveInterval
=
config
.
aliveInterval
||
aliveInterval
crabName
=
config
.
crabName
||
crabName
monitorRegion
=
config
.
monitorRegion
||
monitorRegion
monitorType
=
config
.
monitorType
||
monitorType
base_gp_url
=
config
.
base_gp_url
||
base_gp_url
defaultIntervalTimeForOurApp
=
config
.
defaultIntervalTimeForOurApp
||
defaultIntervalTimeForOurApp
start
=
config
.
start
||
start
dailyOnlineStartHours
=
config
.
dailyOnlineStartHours
||
dailyOnlineStartHours
dailyOnlineEndHours
=
config
.
dailyOnlineEndHours
||
dailyOnlineEndHours
log
(
JSON
.
stringify
(
config
))
log
(
JSON
.
stringify
(
notifyEmail
))
}
})
}
async
function
getTop100
()
{
log
(
`获取以下国家前
${
requestTopAppNum
}
:
${
JSON
.
stringify
(
monitorRegion
)}
`
)
let
regions
=
Object
.
keys
(
monitorRegion
)
let
types
=
Object
.
keys
(
monitorType
)
for
(
let
i
in
regions
)
{
let
region
=
regions
[
i
]
log
(
`地区:
${
region
}
`
)
names
=
monitorNames
[
region
]
||
[]
newForRegion
=
[]
for
(
let
t
in
types
)
{
let
type
=
types
[
t
]
log
(
`分类:
${
type
}
`
)
// 数量分页
let
getTimes
=
Math
.
floor
(
requestTopAppNum
/
120
)
+
1
let
lastGetNum
=
requestTopAppNum
%
120
if
(
getTimes
>
5
)
{
if
(
getTimes
>
6
)
{
lastGetNum
=
120
}
getTimes
=
5
}
for
(
let
i
=
0
;
i
<
getTimes
;
i
++
)
{
let
getNum
=
i
==
getTimes
-
1
&&
lastGetNum
||
119
log
(
`start:
${
i
*
120
}
, pageNum:
${
getNum
}
`
)
await
sleep
(
sleepTime
)
await
gplay
.
list
({
category
:
gplay
.
category
[
type
],
collection
:
gplay
.
collection
.
TOP_FREE
,
num
:
getNum
,
start
:
i
*
120
,
lang
:
region
,
country
:
region
,
fullDetail
:
false
,
requestOptions
:
{
timeout
:
requestTimeout
}
})
.
then
(
res
=>
{
console
.
log
(
`获取到 <
${
monitorRegion
[
region
]}
>[
${
monitorType
[
type
]}
]排名:
${
i
*
120
}
~
${
i
*
120
+
getNum
}
`
)
if
(
res
&&
res
.
length
&&
res
.
length
>
0
)
{
res
.
forEach
(
app
=>
{
// --- 补齐/更新 app 名字, 不管是什么状态的, 前100得肯定都要加入监控, 直接设置名字
status
[
app
.
appId
]
=
{
...(
status
[
app
.
appId
]
||
{}),
appName
:
app
.
title
}
// 补齐这个 app 分类
status
[
app
.
appId
].
category
=
type
if
(
!
names
.
includes
(
app
.
appId
))
{
names
.
push
(
app
.
appId
)
newForRegion
.
push
({
id
:
app
.
appId
,
name
:
app
.
title
,
region
:
monitorRegion
[
region
],
category
:
type
})
log
(
`新加入<
${
monitorRegion
[
region
]}
>[
${
monitorType
[
type
]}
]监控:
${
app
.
appId
}
`
)
}
})
}
})
.
catch
(
err
=>
{
console
.
log
(
`获取排名<
${
monitorRegion
[
region
]}
> 错误:
${
err
.
message
}
`
)
throw
err
})
}
}
if
(
newForRegion
.
length
>
0
)
{
newTopMonitorNames
[
region
]
=
[...(
newTopMonitorNames
[
region
]
&&
newTopMonitorNames
[
region
]
||
[]),
...
newForRegion
]
monitorNames
[
region
]
=
names
}
}
}
async
function
sleepForInterVal
(
val
)
{
log
(
`进行睡眠:
${
lastIntervalTime
}
`
)
await
sleep
(
val
)
}
async
function
monitorIfOnline
(
names
)
{
log
(
`获取数量:
${
names
.
length
}
`
)
for
(
let
i
in
names
)
{
let
name
=
names
[
i
]
log
(
`获取:
${
name
}
`
)
await
sleep
(
sleepTime
)
await
gplay
.
app
({
appId
:
name
,
requestOptions
:
{
timeout
:
requestTimeout
}
})
.
then
((
val
)
=>
{
log
(
`获取到(
${
status
[
name
]
&&
status
[
name
].
category
||
'noType'
}
):
${
name
}
`
)
judgeNewOnline
(
name
)
// judgePermissionChanged(name, val)
status
[
name
]
=
{
...(
status
[
name
]
||
{}),
// permissions: val,
status
:
true
,
date
:
Date
().
toString
()
}
})
.
catch
((
err
)
=>
{
if
(
err
.
toString
().
includes
(
'404'
))
{
console
.
log
(
`获取不到:
${
name
}
, error:
${
err
}
`
)
failedApps
.
push
(
name
)
judgeNewOffline
(
name
)
let
a
=
status
[
name
]
||
{}
status
[
name
]
=
{
...
a
,
status
:
false
,
date
:
Date
().
toString
()
}
}
else
if
(
err
.
toString
().
includes
(
'ETIMEDOUT'
))
{
console
.
log
(
`连接超时:
${
err
.
toString
()}
`
)
throw
err
}
else
{
errorLog
.
push
(
`Motitor Online Error:
${
link
(
name
,
true
)}
-
${
err
.
message
}
`
)
console
.
log
(
`获取在线错误:
${
name
}
,
${
err
.
message
}
`
)
}
})
}
}
function
link
(
name
,
countOurs
)
{
let
ourName
=
isOurs
(
name
,
countOurs
)
return
`
${
ourName
}
<a href="
${
base_gp_url
}${
name
}
">
${
getRegion
(
name
)}
[
${
monitorType
[
status
[
name
]
&&
status
[
name
].
category
||
''
]
||
''
}
] -
${
name
}
<br/>
名字:
${(
status
[
name
]
&&
(
status
[
name
].
appName
||
`(noName:这次更新数据里没有进前
${
requestTopAppNum
}
)`
))}
</a>`
}
function
getRegion
(
name
)
{
let
regions
=
Object
.
keys
(
monitorNames
)
for
(
let
i
in
regions
)
{
let
key
=
regions
[
i
]
if
(
monitorNames
[
key
].
includes
(
name
))
{
return
monitorRegion
[
key
]
||
key
}
}
}
function
markError
()
{
let
emailContent
=
''
log
(
`发生意外错误, 生错错误邮件:
${
errorLog
.
toString
()}
`
)
emailContent
+=
`<details>`
emailContent
+=
`<summary>虫子拿权限发生意外事故</summary>`
emailContent
+=
`<dl>`
errorLog
.
forEach
(
e
=>
{
emailContent
+=
`<dt>
${
e
}
</dt>`
})
emailContent
+=
`</dl>`
emailContent
+=
`</details>`
errorLog
=
[]
return
emailContent
}
function
genMail
()
{
let
firstLine
=
''
// 第一行不用打开邮箱就能显示, 用来展示关键信息
let
emailContent
=
''
let
lastSendListDate
=
new
Date
(
status
.
sendListDate
||
'Tue Jan 29 2019 19:32:24 GMT+0800 (CST)'
)
let
today
=
new
Date
()
let
needSendList
=
(
theDaySendList
.
includes
(
today
.
getDay
()))
&&
(
lastSendListDate
.
toLocaleDateString
()
!=
today
.
toLocaleDateString
())
if
(
!
isFirstRun
&&
!
needSendList
&&
newOffline
.
length
==
0
&&
newOnline
.
length
==
0
&&
Object
.
keys
(
permissionChange
).
length
==
0
&&
Object
.
keys
(
newTopMonitorNames
).
length
==
0
)
{
log
(
`没有更新, 不生成内容邮件`
)
if
(
errorLog
.
length
>
0
)
{
emailContent
+=
`Error:
${
markError
()}
`
return
emailContent
}
return
null
}
log
(
`第一次跑:
${
isFirstRun
}
, 新下:
${
newOffline
.
length
}
, 新上:
${
newOnline
.
length
}
, 权限改变:
${
Object
.
keys
(
permissionChange
).
length
}
`
)
if
(
errorLog
.
length
>
0
)
{
emailContent
+=
markError
()
}
if
(
failedApps
.
length
>
0
&&
isFirstRun
)
{
emailContent
+=
`<div>本次第一次监控</div>`
failedApps
.
forEach
(
name
=>
{
emailContent
+=
`<div>获取失败}:
${
link
(
name
,
true
)}
</div>`
})
}
if
(
isFirstRun
)
{
isFirstRun
=
false
}
if
(
daichaoApps
.
length
==
0
)
{
emailContent
+=
'<div>没有从贷超监控中获取数据</div>'
}
// --------- 判断上下线和进入 top 中我们 app 的数量
let
ourTop
=
[]
let
ourDown
=
ourAppIds
.
filter
(
val
=>
newOffline
.
includes
(
val
))
let
ourUp
=
ourAppIds
.
filter
(
val
=>
newOnline
.
includes
(
val
))
let
daichaoTop
=
[]
let
daichaoDown
=
daichaoApps
.
filter
(
val
=>
newOffline
.
includes
(
val
))
let
daichaoUp
=
daichaoApps
.
filter
(
val
=>
newOnline
.
includes
(
val
))
// --------- 判断上下线和进入 top 中我们 app 的数量
if
(
Object
.
keys
(
newTopMonitorNames
).
length
>
0
)
{
emailContent
+=
`<div>------------从
${
Object
.
keys
(
newTopMonitorNames
).
length
}
个国家新增监控:-----------</div>`
Object
.
keys
(
newTopMonitorNames
).
forEach
(
key
=>
{
let
names
=
newTopMonitorNames
[
key
]
if
(
names
.
length
>
0
)
{
// 判断每个国家新增里自己的 app, 累加
ourTop
=
[...
ourTop
,
...
ourAppIds
.
filter
(
val
=>
names
.
includes
(
val
))]
daichaoTop
=
[...
daichaoTop
,
...
daichaoApps
.
filter
(
val
=>
names
.
includes
(
val
))]
emailContent
+=
wrapSummary
(
`本次从<
${
monitorRegion
[
key
]}
>top
${
requestTopAppNum
}
新增监控:
${
names
.
length
}
个`
,
names
.
map
(
n
=>
`
${
link
(
n
.
id
,
true
)}
进top100`
))
}
})
emailContent
+=
`<br/>/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>`
}
// 自己 app
firstLine
=
`《
${
firstLine
}${
ourUp
.
length
>
0
?
`上
${
ourUp
.
length
}
`
:
''
}
`
firstLine
=
`
${
firstLine
}${
ourDown
.
length
>
0
?
`下
${
ourDown
.
length
}
`
:
''
}
`
firstLine
=
`
${
firstLine
}${
ourTop
.
length
>
0
?
`T
${
ourTop
.
length
}
`
:
''
}
》`
// 贷超
firstLine
=
`
${
firstLine
}
【
${
daichaoUp
.
length
>
0
?
`上
${
daichaoUp
.
length
}
`
:
''
}
`
firstLine
=
`
${
firstLine
}${
daichaoDown
.
length
>
0
?
`下
${
daichaoDown
.
length
}
`
:
''
}
`
firstLine
=
`
${
firstLine
}${
daichaoTop
.
length
>
0
?
`T
${
daichaoTop
.
length
}
`
:
''
}
】`
// 统计
hitOurs
=
ourUp
.
length
+
ourDown
.
length
+
ourTop
.
length
hitDaichao
=
daichaoUp
.
length
+
daichaoDown
.
length
+
daichaoTop
.
length
if
(
newOffline
.
length
==
0
)
{
emailContent
+=
'<div>没有登记中的产品被新下架</div>'
}
else
{
emailContent
+=
`<br/>------------新下架:
${
newOffline
.
length
}
个-----------<br/>`
newOffline
.
forEach
(
name
=>
{
let
his
=
(
status
[
name
]
&&
status
[
name
].
permissionHis
&&
status
[
name
].
permissionHis
)
||
{}
his
.
lastPermissions
=
(
status
[
name
]
&&
status
[
name
].
permissions
&&
status
[
name
].
permissions
)
||
[]
emailContent
+=
getPermissionChangeContent
(
name
,
his
,
`新下架ಥ_ಥ(及上次权限情况)`
)
// emailContent += `<div>检测到新下架ಥ_ಥ: ${link(name)}</div>`
})
emailContent
+=
`<br/>/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>`
}
if
(
newOnline
.
length
==
0
)
{
emailContent
+=
`<div>没有登记中的产品新上架</div>`
}
else
{
emailContent
+=
`<div>-----------新上架:
${
newOnline
.
length
}
个---------------------</div>`
newOnline
.
forEach
(
name
=>
{
if
(
permissionChange
[
name
])
{
emailContent
+=
getPermissionChangeContent
(
name
,
permissionChange
[
name
],
`新上架😃: `
)
emailContent
+=
`<br/>/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>`
delete
permissionChange
[
name
]
}
else
{
emailContent
+=
wrapSummary
(
`<div>新上架^_^:
${
link
(
name
,
true
)}
</div>`
,
((
status
[
name
]
&&
status
[
name
].
permissions
&&
status
[
name
].
permissions
)
||
[]))
emailContent
+=
`<br/>/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>`
}
})
}
if
(
Object
.
keys
(
permissionChange
).
length
==
0
)
{
emailContent
+=
`<div>没有检测到有产品仅权限改变</div>`
}
else
{
log
(
'监测到有权限改变'
)
emailContent
+=
`<br/>---------------权限改变:
${
Object
.
keys
(
permissionChange
).
length
}
个-------------<br/>`
Object
.
keys
(
permissionChange
).
forEach
(
val
=>
{
emailContent
+=
getPermissionChangeContent
(
val
,
permissionChange
[
val
])
})
emailContent
+=
`<br/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>`
}
// 发送当前监控列表
if
(
needSendList
)
{
emailContent
+=
`<br/><br/><br/>`
let
countrys
=
Object
.
keys
(
monitorRegion
)
monitorRegion
emailContent
+=
`<div>下面是监控列表<br/>当前监控
${
countrys
.
length
}
个国家</div>`
let
total
=
0
Object
.
keys
(
monitorNames
).
forEach
(
val
=>
{
let
num
=
monitorNames
[
val
].
length
total
+=
num
emailContent
+=
wrapSummary
(
`
${
monitorRegion
[
val
]
||
val
}
(
${
num
}
个)`
,
monitorNames
[
val
].
map
(
id
=>
link
(
id
,
false
)))
})
emailContent
+=
`<div>监控总数量:
${
total
}
</div>`
status
.
sendListDate
=
today
.
toString
()
}
emailContent
+=
`<br/><br/><br/>
${
new
Date
().
toLocaleString
()}
`
log
(
`生成邮件内容: \n
${
emailContent
}
`
)
// 清空临时栈
newOffline
=
[]
newOnline
=
[]
permissionChange
=
{}
failedApps
=
[]
errorLog
=
[]
newTopMonitorNames
=
{}
return
`<div>
${
firstLine
}
</div><br/>
${
emailContent
}
`
}
function
isOurs
(
name
,
countOurs
)
{
if
(
daichaoApps
.
includes
(
name
))
{
return
"🏦(贷超)"
}
if
(
ourAppIds
.
includes
(
name
))
{
return
`📌(
${
ourApps
[
name
]
||
'No Name in Gitlab'
}
)`
}
return
''
}
function
getPermissionChangeContent
(
id
,
obj
,
title
)
{
changes
=
[]
if
(
obj
.
adds
&&
obj
.
adds
.
length
>
0
)
{
changes
.
push
(
wrapSummary
(
`添加`
,
obj
.
adds
,
"green"
))
}
if
(
obj
.
deletes
&&
obj
.
deletes
.
length
>
0
)
{
changes
.
push
(
wrapSummary
(
`删除`
,
obj
.
deletes
,
"red"
))
}
if
(
obj
.
stills
&&
obj
.
stills
.
length
>
0
)
{
changes
.
push
(
wrapSummary
(
`保留`
,
obj
.
stills
,
"gray"
))
}
if
(
obj
.
newPermission
&&
obj
.
newPermission
.
length
>
0
)
{
changes
.
push
(
wrapSummary
(
`新权限`
,
obj
.
newPermission
))
}
if
(
obj
.
lastPermissions
&&
obj
.
lastPermissions
.
length
>
0
)
{
changes
.
push
(
wrapSummary
(
`旧权限`
,
obj
.
lastPermissions
))
}
log
(
`权限改变:
${
id
}
:
${
changes
.
length
}
`
)
return
wrapSummary
(
`- <div>
${
title
||
'权限改变'
}
:<br/>
${
link
(
id
,
true
)}
</div>`
,
changes
)
}
function
setPermissionHis
(
name
,
obj
)
{
status
[
name
].
permissionHis
=
{
adds
:
obj
.
adds
,
deletes
:
obj
.
deletes
,
stills
:
obj
.
stills
}
}
function
aliveContent
(
date
,
lastSend
)
{
let
emailContent
=
''
emailContent
+=
`<div>现在是:
${
date
.
toLocaleString
()}
, 监控还活着</div>`
let
allN
=
allNames
(
monitorNames
).
length
emailContent
+=
`<div>当前总监控:
${
allN
}
, \n设置间隔时间:
${(
lastIntervalTime
/
minute
)}
\n上次记录存活时间:
${
lastSend
.
toLocaleString
()}
</div>`
log
(
emailContent
)
return
emailContent
}
function
sendEmail
(
content
,
to
=
notifyEmail
)
{
if
(
content
==
null
||
content
==
undefined
||
content
==
''
)
{
console
.
log
(
'没有生成内容, 检查心跳'
)
let
date
=
new
Date
()
let
lastDing
=
new
Date
(
status
.
lastDingDate
||
'Tue Jan 29 2019 19:32:24 GMT+0800 (CST)'
)
let
lastSend
=
new
Date
(
status
.
lastSendDate
||
'Tue Jan 29 2019 19:32:24 GMT+0800 (CST)'
)
if
((
date
.
getHours
()
-
lastDing
.
getHours
())
>=
aliveInterval
)
{
log
(
'钉钉发送心跳'
)
dingDing
(
aliveContent
(
date
,
lastDing
))
status
[
'lastDingDate'
]
=
date
.
toString
()
}
if
(
date
.
toLocaleDateString
()
!=
lastSend
.
toLocaleDateString
())
{
// 不是同一天, 且是9点, 发送, 发送后重新保存发送时间为当天, 当天的就不会发送是否还活着
log
(
`当前时间:
${
date
.
toLocaleString
()}
, 上次存活提示时间:
${
lastSend
.
toLocaleString
()}
`
)
if
(
date
.
getHours
()
>
aliveTime
)
{
log
(
`发送心跳`
)
content
=
aliveContent
(
date
,
lastSend
)
status
[
'lastSendDate'
]
=
date
.
toString
()
}
else
{
return
}
}
else
{
return
}
return
}
console
.
log
(
`发送email:
${
content
.
length
}
`
)
if
(
content
.
indexOf
(
'Error'
)
!=
-
1
)
{
to
=
developer
}
else
{
// to = [...to, 添加只对自己app监控的人]
}
let
myEmail
=
'chaolun.ni@starwin.com'
let
emailTo
=
to
.
join
(
', '
)
let
trans
=
nodemailer
.
createTransport
({
host
:
'smtp.exmail.qq.com'
,
port
:
587
,
secure
:
false
,
auth
:
{
user
:
myEmail
,
pass
:
'3JkTpbNQ3DeNRJbu'
}
})
let
appendTitle
=
hitOurs
>
0
?
`📌
${
hitOurs
}
`
:
''
appendTitle
=
hitDaichao
>
0
?
`
${
appendTitle
}
🏦
${
hitDaichao
}
`
:
`
${
appendTitle
}
`
let
mailOption
=
{
from
:
myEmail
,
to
:
emailTo
,
subject
:
`
${
appendTitle
}
.
${
crabName
}
`
,
text
:
content
,
html
:
content
,
}
trans
.
sendMail
(
mailOption
,
(
error
,
info
)
=>
{
if
(
error
)
{
return
console
.
log
(
`发生错误:
${
error
}
`
);
}
console
.
log
(
`message
${
info
.
messageId
}
send:
${
info
.
response
}
`
)
})
dingDing
(
content
,
notifyDingding
)
// 清空计数
hitDaichao
=
0
hitOurs
=
0
}
function
dingDing
(
content
,
toDing
=
debugDingding
)
{
log
(
`发送钉钉~`
)
content
=
`
${
crabName
}
\n`
+
content
request
.
post
(
toDing
,
{
headers
:
{
'content-type'
:
'application/json;charset=utf-8'
},
body
:
JSON
.
stringify
({
msgtype
:
'text'
,
text
:
{
content
:
content
}
})
},
(
err
,
param
)
=>
param
.
statusCode
!=
200
&&
log
(
`Error:
${
err
}
\nParam:
${
JSON
.
stringify
(
param
)}
`
))
}
function
sleep
(
ms
)
{
return
new
Promise
(
resolve
=>
setTimeout
(
resolve
,
ms
));
}
function
judgeNewOnline
(
name
)
{
if
(
status
[
name
]
&&
status
[
name
].
status
==
false
)
{
log
(
`
${
name
}
新上架 😃`
)
newOnline
.
push
(
name
)
}
}
function
judgeNewOffline
(
name
)
{
if
(
status
[
name
]
&&
status
[
name
].
status
==
true
)
{
log
(
`
${
name
}
被下架了 ಥ_ಥ`
)
newOffline
.
push
(
name
)
}
}
function
judgePermissionChanged
(
name
,
newPermission
)
{
log
(
`检查
${
name
}
权限是否变化`
)
if
(
status
[
name
]
==
undefined
||
status
[
name
].
permissions
==
undefined
)
{
log
(
`拿不到这个名字
${
name
}
记录, 不做权限变化检测了`
)
return
}
let
oldPermissions
=
(
status
[
name
]
&&
status
[
name
].
permissions
&&
status
[
name
].
permissions
)
||
[]
let
oldPSet
=
new
Set
(
oldPermissions
)
let
newPSet
=
new
Set
(
newPermission
||
[])
let
deletes
=
new
Set
([...
oldPSet
].
filter
(
x
=>
!
newPSet
.
has
(
x
)))
let
adds
=
new
Set
([...
newPSet
].
filter
(
x
=>
!
oldPSet
.
has
(
x
)))
let
stills
=
new
Set
([...
oldPSet
].
filter
(
x
=>
newPSet
.
has
(
x
)))
let
situation
=
{
adds
:
Array
.
from
(
adds
),
deletes
:
Array
.
from
(
deletes
),
stills
:
Array
.
from
(
stills
),
}
if
(
oldPermissions
.
length
!=
newPermission
.
length
)
{
log
(
`
${
name
}
有权限改变`
)
permissionChange
[
name
]
=
{
name
:
name
,
newPermission
:
newPermission
,
lastPermissions
:
oldPermissions
,
...
situation
,
}
setPermissionHis
(
name
,
situation
)
return
}
if
(
deletes
.
size
>
0
||
adds
.
size
>
0
)
{
log
(
`
${
name
}
有权限改变`
)
permissionChange
[
name
]
=
{
name
:
name
,
newPermission
:
newPermission
,
lastPermissions
:
oldPermissions
,
...
situation
,
}
setPermissionHis
(
name
,
situation
)
}
}
function
wrapSummary
(
title
,
list
,
color
=
'black'
)
{
let
emailContent
=
''
emailContent
+=
`<details style="color:
${
color
}
">`
emailContent
+=
`<summary>
${
title
}
: </summary>`
emailContent
+=
`<dl>`
list
.
forEach
(
l
=>
{
emailContent
+=
`<dt>-
${
l
}
</dt>`
})
emailContent
+=
`</dl>`
emailContent
+=
`</details>`
return
emailContent
}
function
isInTimeInRangeToday
(
start
,
end
)
{
let
dayKey
=
"lastDailyOnlinesAppsDate"
let
now
=
new
Date
()
let
lastDate
=
new
Date
(
status
[
dayKey
]
||
'Tue Jan 29 2019 19:32:24 GMT+0800 (CST)'
)
lastDate
.
setHours
(
lastDate
.
getHours
()
+
24
)
if
(
start
<
now
.
getHours
()
&&
now
.
getHours
()
<
end
&&
now
>
lastDate
)
{
status
[
dayKey
]
=
Date
()
return
true
}
return
false
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment