Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
CAP
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
tsai
CAP
Commits
1d67da71
Commit
1d67da71
authored
Nov 05, 2019
by
Savorboard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add dashboard api interface
parent
c633a6e5
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
318 additions
and
0 deletions
+318
-0
IMonitoringApi.MySql.cs
src/DotNetCore.CAP.MySql/IMonitoringApi.MySql.cs
+217
-0
IMonitoringApi.cs
src/DotNetCore.CAP/Monitoring/IMonitoringApi.cs
+34
-0
MessageDto.cs
src/DotNetCore.CAP/Monitoring/MessageDto.cs
+28
-0
MessageQueryDto.cs
src/DotNetCore.CAP/Monitoring/MessageQueryDto.cs
+23
-0
StatisticsDto.cs
src/DotNetCore.CAP/Monitoring/StatisticsDto.cs
+16
-0
No files found.
src/DotNetCore.CAP.MySql/IMonitoringApi.MySql.cs
0 → 100644
View file @
1d67da71
// Copyright (c) .NET Core Community. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using
System
;
using
System.Collections.Generic
;
using
System.Data
;
using
System.Linq
;
using
System.Threading.Tasks
;
using
Dapper
;
using
DotNetCore.CAP.Internal
;
using
DotNetCore.CAP.Messages
;
using
DotNetCore.CAP.Monitoring
;
using
DotNetCore.CAP.Persistence
;
using
Microsoft.Extensions.Options
;
using
MySql.Data.MySqlClient
;
namespace
DotNetCore.CAP.MySql
{
internal
class
MySqlMonitoringApi
:
IMonitoringApi
{
private
readonly
IOptions
<
MySqlOptions
>
_options
;
private
readonly
string
_prefix
;
public
MySqlMonitoringApi
(
IOptions
<
MySqlOptions
>
options
)
{
_options
=
options
;
_prefix
=
options
.
Value
.
TableNamePrefix
??
throw
new
ArgumentNullException
(
nameof
(
options
));
}
public
StatisticsDto
GetStatistics
()
{
var
sql
=
string
.
Format
(
@"
set transaction isolation level read committed;
select count(Id) from `{0}.published` where StatusName = N'Succeeded';
select count(Id) from `{0}.received` where StatusName = N'Succeeded';
select count(Id) from `{0}.published` where StatusName = N'Failed';
select count(Id) from `{0}.received` where StatusName = N'Failed';"
,
_prefix
);
var
statistics
=
UseConnection
(
connection
=>
{
var
stats
=
new
StatisticsDto
();
using
(
var
multi
=
connection
.
QueryMultiple
(
sql
))
{
stats
.
PublishedSucceeded
=
multi
.
ReadSingle
<
int
>();
stats
.
ReceivedSucceeded
=
multi
.
ReadSingle
<
int
>();
stats
.
PublishedFailed
=
multi
.
ReadSingle
<
int
>();
stats
.
ReceivedFailed
=
multi
.
ReadSingle
<
int
>();
}
return
stats
;
});
return
statistics
;
}
public
IDictionary
<
DateTime
,
int
>
HourlyFailedJobs
(
MessageType
type
)
{
var
tableName
=
type
==
MessageType
.
Publish
?
"published"
:
"received"
;
return
UseConnection
(
connection
=>
GetHourlyTimelineStats
(
connection
,
tableName
,
nameof
(
StatusName
.
Failed
)));
}
public
IDictionary
<
DateTime
,
int
>
HourlySucceededJobs
(
MessageType
type
)
{
var
tableName
=
type
==
MessageType
.
Publish
?
"published"
:
"received"
;
return
UseConnection
(
connection
=>
GetHourlyTimelineStats
(
connection
,
tableName
,
nameof
(
StatusName
.
Succeeded
)));
}
public
IList
<
MessageDto
>
Messages
(
MessageQueryDto
queryDto
)
{
var
tableName
=
queryDto
.
MessageType
==
MessageType
.
Publish
?
"published"
:
"received"
;
var
where
=
string
.
Empty
;
if
(!
string
.
IsNullOrEmpty
(
queryDto
.
StatusName
))
{
where
+=
" and StatusName=@StatusName"
;
}
if
(!
string
.
IsNullOrEmpty
(
queryDto
.
Name
))
{
where
+=
" and Name=@Name"
;
}
if
(!
string
.
IsNullOrEmpty
(
queryDto
.
Group
))
{
where
+=
" and `Group`=@Group"
;
}
if
(!
string
.
IsNullOrEmpty
(
queryDto
.
Content
))
{
where
+=
" and Content like '%@Content%'"
;
}
var
sqlQuery
=
$"select * from `
{
_prefix
}
.
{
tableName
}
` where 1=1
{
where
}
order by Added desc limit @Limit offset @Offset"
;
return
UseConnection
(
conn
=>
conn
.
Query
<
MessageDto
>(
sqlQuery
,
new
{
queryDto
.
StatusName
,
queryDto
.
Group
,
queryDto
.
Name
,
queryDto
.
Content
,
Offset
=
queryDto
.
CurrentPage
*
queryDto
.
PageSize
,
Limit
=
queryDto
.
PageSize
}).
ToList
());
}
public
int
PublishedFailedCount
()
{
return
UseConnection
(
conn
=>
GetNumberOfMessage
(
conn
,
"published"
,
nameof
(
StatusName
.
Failed
)));
}
public
int
PublishedSucceededCount
()
{
return
UseConnection
(
conn
=>
GetNumberOfMessage
(
conn
,
"published"
,
nameof
(
StatusName
.
Succeeded
)));
}
public
int
ReceivedFailedCount
()
{
return
UseConnection
(
conn
=>
GetNumberOfMessage
(
conn
,
"received"
,
nameof
(
StatusName
.
Failed
)));
}
public
int
ReceivedSucceededCount
()
{
return
UseConnection
(
conn
=>
GetNumberOfMessage
(
conn
,
"received"
,
nameof
(
StatusName
.
Succeeded
)));
}
private
int
GetNumberOfMessage
(
IDbConnection
connection
,
string
tableName
,
string
statusName
)
{
var
sqlQuery
=
$"select count(Id) from `
{
_prefix
}
.
{
tableName
}
` where StatusName = @state"
;
var
count
=
connection
.
ExecuteScalar
<
int
>(
sqlQuery
,
new
{
state
=
statusName
});
return
count
;
}
private
T
UseConnection
<
T
>(
Func
<
IDbConnection
,
T
>
action
)
{
return
action
(
new
MySqlConnection
(
_options
.
Value
.
ConnectionString
));
}
private
Dictionary
<
DateTime
,
int
>
GetHourlyTimelineStats
(
IDbConnection
connection
,
string
tableName
,
string
statusName
)
{
var
endDate
=
DateTime
.
Now
;
var
dates
=
new
List
<
DateTime
>();
for
(
var
i
=
0
;
i
<
24
;
i
++)
{
dates
.
Add
(
endDate
);
endDate
=
endDate
.
AddHours
(-
1
);
}
var
keyMaps
=
dates
.
ToDictionary
(
x
=>
x
.
ToString
(
"yyyy-MM-dd-HH"
),
x
=>
x
);
return
GetTimelineStats
(
connection
,
tableName
,
statusName
,
keyMaps
);
}
private
Dictionary
<
DateTime
,
int
>
GetTimelineStats
(
IDbConnection
connection
,
string
tableName
,
string
statusName
,
IDictionary
<
string
,
DateTime
>
keyMaps
)
{
var
sqlQuery
=
$@"
select aggr.* from (
select date_format(`Added`,'%Y-%m-%d-%H') as `Key`,
count(id) `Count`
from `
{
_prefix
}
.
{
tableName
}
`
where StatusName = @statusName
group by date_format(`Added`,'%Y-%m-%d-%H')
) aggr where `Key` in @keys;"
;
var
valuesMap
=
connection
.
Query
<
TimelineCounter
>(
sqlQuery
,
new
{
keys
=
keyMaps
.
Keys
,
statusName
})
.
ToDictionary
(
x
=>
x
.
Key
,
x
=>
x
.
Count
);
foreach
(
var
key
in
keyMaps
.
Keys
)
{
if
(!
valuesMap
.
ContainsKey
(
key
))
{
valuesMap
.
Add
(
key
,
0
);
}
}
var
result
=
new
Dictionary
<
DateTime
,
int
>();
for
(
var
i
=
0
;
i
<
keyMaps
.
Count
;
i
++)
{
var
value
=
valuesMap
[
keyMaps
.
ElementAt
(
i
).
Key
];
result
.
Add
(
keyMaps
.
ElementAt
(
i
).
Value
,
value
);
}
return
result
;
}
public
async
Task
<
MediumMessage
>
GetPublishedMessageAsync
(
long
id
)
{
var
sql
=
$@"SELECT * FROM `
{
_prefix
}
.published` WHERE `Id`=
{
id
}
;"
;
await
using
var
connection
=
new
MySqlConnection
(
_options
.
Value
.
ConnectionString
);
return
await
connection
.
QueryFirstOrDefaultAsync
<
MediumMessage
>(
sql
);
}
public
async
Task
<
MediumMessage
>
GetReceivedMessageAsync
(
long
id
)
{
var
sql
=
$@"SELECT * FROM `
{
_prefix
}
.received` WHERE Id=
{
id
}
;"
;
await
using
var
connection
=
new
MySqlConnection
(
_options
.
Value
.
ConnectionString
);
return
await
connection
.
QueryFirstOrDefaultAsync
<
MediumMessage
>(
sql
);
}
}
class
TimelineCounter
{
public
string
Key
{
get
;
set
;
}
public
int
Count
{
get
;
set
;
}
}
}
\ No newline at end of file
src/DotNetCore.CAP/Monitoring/IMonitoringApi.cs
0 → 100644
View file @
1d67da71
// Copyright (c) .NET Core Community. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using
System
;
using
System.Collections.Generic
;
using
System.Threading.Tasks
;
using
DotNetCore.CAP.Messages
;
using
DotNetCore.CAP.Persistence
;
namespace
DotNetCore.CAP.Monitoring
{
public
interface
IMonitoringApi
{
Task
<
MediumMessage
>
GetPublishedMessageAsync
(
long
id
);
Task
<
MediumMessage
>
GetReceivedMessageAsync
(
long
id
);
StatisticsDto
GetStatistics
();
IList
<
MessageDto
>
Messages
(
MessageQueryDto
queryDto
);
int
PublishedFailedCount
();
int
PublishedSucceededCount
();
int
ReceivedFailedCount
();
int
ReceivedSucceededCount
();
IDictionary
<
DateTime
,
int
>
HourlySucceededJobs
(
MessageType
type
);
IDictionary
<
DateTime
,
int
>
HourlyFailedJobs
(
MessageType
type
);
}
}
\ No newline at end of file
src/DotNetCore.CAP/Monitoring/MessageDto.cs
0 → 100644
View file @
1d67da71
// Copyright (c) .NET Core Community. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using
System
;
namespace
DotNetCore.CAP.Monitoring
{
public
class
MessageDto
{
public
long
Id
{
get
;
set
;
}
public
string
Version
{
get
;
set
;
}
public
string
Group
{
get
;
set
;
}
public
string
Name
{
get
;
set
;
}
public
string
Content
{
get
;
set
;
}
public
DateTime
Added
{
get
;
set
;
}
public
DateTime
?
ExpiresAt
{
get
;
set
;
}
public
int
Retries
{
get
;
set
;
}
public
string
StatusName
{
get
;
set
;
}
}
}
\ No newline at end of file
src/DotNetCore.CAP/Monitoring/MessageQueryDto.cs
0 → 100644
View file @
1d67da71
// Copyright (c) .NET Core Community. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using
DotNetCore.CAP.Messages
;
namespace
DotNetCore.CAP.Monitoring
{
public
class
MessageQueryDto
{
public
MessageType
MessageType
{
get
;
set
;
}
public
string
Group
{
get
;
set
;
}
public
string
Name
{
get
;
set
;
}
public
string
Content
{
get
;
set
;
}
public
string
StatusName
{
get
;
set
;
}
public
int
CurrentPage
{
get
;
set
;
}
public
int
PageSize
{
get
;
set
;
}
}
}
\ No newline at end of file
src/DotNetCore.CAP/Monitoring/StatisticsDto.cs
0 → 100644
View file @
1d67da71
// Copyright (c) .NET Core Community. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
namespace
DotNetCore.CAP.Monitoring
{
public
class
StatisticsDto
{
public
int
Servers
{
get
;
set
;
}
public
int
PublishedSucceeded
{
get
;
set
;
}
public
int
ReceivedSucceeded
{
get
;
set
;
}
public
int
PublishedFailed
{
get
;
set
;
}
public
int
ReceivedFailed
{
get
;
set
;
}
}
}
\ No newline at end of file
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