mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-12 06:24:10 +01:00
console: add an API to get flow rate
This commit is contained in:
@@ -55,8 +55,9 @@ func (c *Component) Start() error {
|
|||||||
|
|
||||||
c.d.HTTP.AddHandler("/", netHTTP.HandlerFunc(c.assetsHandlerFunc))
|
c.d.HTTP.AddHandler("/", netHTTP.HandlerFunc(c.assetsHandlerFunc))
|
||||||
c.d.HTTP.GinRouter.GET("/api/v0/console/docs/:name", c.docsHandlerFunc)
|
c.d.HTTP.GinRouter.GET("/api/v0/console/docs/:name", c.docsHandlerFunc)
|
||||||
c.d.HTTP.GinRouter.GET("/api/v0/console/last-flow", c.apiLastFlowHandlerFunc)
|
c.d.HTTP.GinRouter.GET("/api/v0/console/widget/flow-last", c.widgetFlowLastHandlerFunc)
|
||||||
c.d.HTTP.GinRouter.GET("/api/v0/console/exporters", c.apiExportersHandlerFunc)
|
c.d.HTTP.GinRouter.GET("/api/v0/console/widget/flow-rate", c.widgetFlowRateHandlerFunc)
|
||||||
|
c.d.HTTP.GinRouter.GET("/api/v0/console/widget/exporters", c.widgetExportersHandlerFunc)
|
||||||
|
|
||||||
c.t.Go(func() error {
|
c.t.Go(func() error {
|
||||||
select {
|
select {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Component) apiLastFlowHandlerFunc(gc *gin.Context) {
|
func (c *Component) widgetFlowLastHandlerFunc(gc *gin.Context) {
|
||||||
ctx := c.t.Context(gc.Request.Context())
|
ctx := c.t.Context(gc.Request.Context())
|
||||||
rows, err := c.d.ClickHouseDB.Conn.Query(ctx,
|
rows, err := c.d.ClickHouseDB.Conn.Query(ctx,
|
||||||
`SELECT * FROM flows WHERE TimeReceived = (SELECT MAX(TimeReceived) FROM flows) LIMIT 1`)
|
`SELECT * FROM flows WHERE TimeReceived = (SELECT MAX(TimeReceived) FROM flows) LIMIT 1`)
|
||||||
@@ -42,7 +42,28 @@ func (c *Component) apiLastFlowHandlerFunc(gc *gin.Context) {
|
|||||||
gc.IndentedJSON(http.StatusOK, response)
|
gc.IndentedJSON(http.StatusOK, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Component) apiExportersHandlerFunc(gc *gin.Context) {
|
func (c *Component) widgetFlowRateHandlerFunc(gc *gin.Context) {
|
||||||
|
ctx := c.t.Context(gc.Request.Context())
|
||||||
|
row := c.d.ClickHouseDB.Conn.QueryRow(ctx,
|
||||||
|
`SELECT COUNT(*)/300 AS rate FROM flows WHERE TimeReceived > date_sub(minute, 5, now())`)
|
||||||
|
if err := row.Err(); err != nil {
|
||||||
|
c.r.Err(err).Msg("unable to query database")
|
||||||
|
gc.JSON(http.StatusInternalServerError, gin.H{"message": "Unable to query database."})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var result float64
|
||||||
|
if err := row.Scan(&result); err != nil {
|
||||||
|
c.r.Err(err).Msg("unable to parse result")
|
||||||
|
gc.JSON(http.StatusInternalServerError, gin.H{"message": "Unable to parse result."})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
gc.IndentedJSON(http.StatusOK, gin.H{
|
||||||
|
"rate": result,
|
||||||
|
"period": "second",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Component) widgetExportersHandlerFunc(gc *gin.Context) {
|
||||||
ctx := c.t.Context(gc.Request.Context())
|
ctx := c.t.Context(gc.Request.Context())
|
||||||
|
|
||||||
exporters := []struct {
|
exporters := []struct {
|
||||||
@@ -17,7 +17,7 @@ import (
|
|||||||
"akvorado/common/reporter"
|
"akvorado/common/reporter"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAPILastFlow(t *testing.T) {
|
func TestWidgetLastFlow(t *testing.T) {
|
||||||
r := reporter.NewMock(t)
|
r := reporter.NewMock(t)
|
||||||
ch, mockConn := clickhousedb.NewMock(t, r)
|
ch, mockConn := clickhousedb.NewMock(t, r)
|
||||||
h := http.NewMock(t, r)
|
h := http.NewMock(t, r)
|
||||||
@@ -89,7 +89,7 @@ func TestAPILastFlow(t *testing.T) {
|
|||||||
|
|
||||||
helpers.TestHTTPEndpoints(t, h.Address, helpers.HTTPEndpointCases{
|
helpers.TestHTTPEndpoints(t, h.Address, helpers.HTTPEndpointCases{
|
||||||
{
|
{
|
||||||
URL: "/api/v0/console/last-flow",
|
URL: "/api/v0/console/widget/flow-last",
|
||||||
ContentType: "application/json; charset=utf-8",
|
ContentType: "application/json; charset=utf-8",
|
||||||
FirstLines: []string{
|
FirstLines: []string{
|
||||||
`{`,
|
`{`,
|
||||||
@@ -106,7 +106,44 @@ func TestAPILastFlow(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAPIExporters(t *testing.T) {
|
func TestFlowRate(t *testing.T) {
|
||||||
|
r := reporter.NewMock(t)
|
||||||
|
ch, mockConn := clickhousedb.NewMock(t, r)
|
||||||
|
h := http.NewMock(t, r)
|
||||||
|
c, err := New(r, Configuration{}, Dependencies{
|
||||||
|
Daemon: daemon.NewMock(t),
|
||||||
|
HTTP: h,
|
||||||
|
ClickHouseDB: ch,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("New() error:\n%+v", err)
|
||||||
|
}
|
||||||
|
helpers.StartStop(t, c)
|
||||||
|
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
mockRow := mocks.NewMockRow(ctrl)
|
||||||
|
mockRow.EXPECT().Err().Return(nil)
|
||||||
|
mockRow.EXPECT().Scan(gomock.Any()).SetArg(0, float64(100.1)).Return(nil)
|
||||||
|
mockConn.EXPECT().
|
||||||
|
QueryRow(gomock.Any(),
|
||||||
|
`SELECT COUNT(*)/300 AS rate FROM flows WHERE TimeReceived > date_sub(minute, 5, now())`).
|
||||||
|
Return(mockRow)
|
||||||
|
|
||||||
|
helpers.TestHTTPEndpoints(t, h.Address, helpers.HTTPEndpointCases{
|
||||||
|
{
|
||||||
|
URL: "/api/v0/console/widget/flow-rate",
|
||||||
|
ContentType: "application/json; charset=utf-8",
|
||||||
|
FirstLines: []string{
|
||||||
|
`{`,
|
||||||
|
` "period": "second",`,
|
||||||
|
` "rate": 100.1`,
|
||||||
|
`}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWidgetExporters(t *testing.T) {
|
||||||
r := reporter.NewMock(t)
|
r := reporter.NewMock(t)
|
||||||
ch, mockConn := clickhousedb.NewMock(t, r)
|
ch, mockConn := clickhousedb.NewMock(t, r)
|
||||||
h := http.NewMock(t, r)
|
h := http.NewMock(t, r)
|
||||||
@@ -135,7 +172,7 @@ func TestAPIExporters(t *testing.T) {
|
|||||||
|
|
||||||
helpers.TestHTTPEndpoints(t, h.Address, helpers.HTTPEndpointCases{
|
helpers.TestHTTPEndpoints(t, h.Address, helpers.HTTPEndpointCases{
|
||||||
{
|
{
|
||||||
URL: "/api/v0/console/exporters",
|
URL: "/api/v0/console/widget/exporters",
|
||||||
ContentType: "application/json; charset=utf-8",
|
ContentType: "application/json; charset=utf-8",
|
||||||
FirstLines: []string{
|
FirstLines: []string{
|
||||||
`{`,
|
`{`,
|
||||||
Reference in New Issue
Block a user