Skip to content

Commit ef1d2dc

Browse files
Ticket #14 : Add monitoring on function
1 parent a483e6f commit ef1d2dc

24 files changed

+539
-126
lines changed

PrometheusDockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM prom/prometheus
2+
3+
COPY conf/docker/prometheus/ /etc/prometheus/
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# my global config
2+
global:
3+
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
4+
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
5+
# scrape_timeout is set to the global default (10s).
6+
7+
# Alertmanager configuration
8+
alerting:
9+
alertmanagers:
10+
- static_configs:
11+
- targets:
12+
# - alertmanager:9093
13+
14+
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
15+
rule_files:
16+
# - "first_rules.yml"
17+
# - "second_rules.yml"
18+
19+
# A scrape configuration containing exactly one endpoint to scrape:
20+
# Here it's Prometheus itself.
21+
scrape_configs:
22+
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
23+
- job_name: "prometheus"
24+
file_sd_configs:
25+
- files:
26+
- 'targets.json'
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[
2+
{
3+
"labels": {
4+
"job": "node"
5+
},
6+
"targets": [
7+
"test-entry.test.svc.cluster.local"
8+
]
9+
}
10+
]

default.ps1

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,13 @@ task buildLocalDockerImage -depends publish {
7676
exec { docker build -f KubernetesDockerfile -t localhost:5000/faaskubernetes . }
7777
exec { docker build -f GatewayDockerfile -t localhost:5000/faasgateway . }
7878
exec { docker build -f WebsiteDockerfile -t localhost:5000/faaswebsite . }
79+
exec { docker build -f PrometheusDockerfile -t localhost:5000/faasprometheus . }
7980
exec { docker push localhost:5000/faasgetsql }
8081
exec { docker push localhost:5000/faastransform }
8182
exec { docker push localhost:5000/faaskubernetes }
8283
exec { docker push localhost:5000/faasgateway }
8384
exec { docker push localhost:5000/faaswebsite }
85+
exec { docker push localhost:5000/faasprometheus }
8486
}
8587

8688
task initLocalKubernetes {
@@ -94,6 +96,8 @@ task initLocalKubernetes {
9496
exec { kubectl apply -f ./kubernetes/faas-gateway-svc.yml --namespace=faas }
9597
exec { kubectl apply -f ./kubernetes/run-website.yml --namespace=faas }
9698
exec { kubectl apply -f ./kubernetes/faas-website-svc.yml --namespace=faas }
99+
exec { kubectl apply -f ./kubernetes/run-prometheus.yml --namespace=faas }
100+
exec { kubectl apply -f ./kubernetes/faas-prometheus-svc.yml --namespace=faas }
97101
}
98102

99103
task builderDockerImage -depends publish {

kubernetes/faas-prometheus-svc.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: faas-prometheus-entry
5+
spec:
6+
type: NodePort
7+
selector:
8+
run: faas-prometheus
9+
ports:
10+
- port: 9090
11+
protocol: TCP
12+
targetPort: 9090
13+
nodePort: 30004

kubernetes/run-prometheus.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: faas-prometheus
5+
spec:
6+
selector:
7+
matchLabels:
8+
run: faas-prometheus
9+
replicas: 1
10+
template:
11+
metadata:
12+
labels:
13+
run: faas-prometheus
14+
spec:
15+
containers:
16+
- name: faas-website
17+
image: localhost:5000/faasprometheus
18+
ports:
19+
- containerPort: 9090

src/FaasNet.Runtime.GetSql/FaasNet.Runtime.GetSql.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
<ItemGroup>
1313
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.11.1" />
1414
<PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
15+
<PackageReference Include="prometheus-net.AspNetCore" Version="5.0.1" />
1516
</ItemGroup>
1617
</Project>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using FaasNet.Runtime.Parameters;
2+
using Microsoft.AspNetCore.Http;
3+
using Newtonsoft.Json;
4+
using System;
5+
using System.IO;
6+
using System.Net;
7+
using System.Threading.Tasks;
8+
9+
namespace FaasNet.Runtime.GetSql.Middlewares
10+
{
11+
public class FunctionMiddleware
12+
{
13+
private readonly RequestDelegate _request;
14+
15+
public FunctionMiddleware(RequestDelegate request)
16+
{
17+
_request = request;
18+
}
19+
20+
public async Task Invoke(HttpContext context)
21+
{
22+
if (context.Request.Method != HttpMethods.Post)
23+
{
24+
await _request.Invoke(context);
25+
return;
26+
}
27+
28+
var functionHandler = new FunctionHandler();
29+
try
30+
{
31+
var requestBody = await GetRequest(context.Request.Body);
32+
var parameter = JsonConvert.DeserializeObject<FunctionParameter<GetSqlConfiguration>>(requestBody);
33+
var result = await functionHandler.Handle(parameter);
34+
context.Response.StatusCode = 200;
35+
context.Response.ContentType = "application/json";
36+
await context.Response.WriteAsync(result.ToString());
37+
}
38+
catch (Exception ex)
39+
{
40+
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
41+
await context.Response.WriteAsync(ex.Message);
42+
}
43+
}
44+
45+
private Task<string> GetRequest(Stream inputBody)
46+
{
47+
using (var reader = new StreamReader(inputBody))
48+
{
49+
return reader.ReadToEndAsync();
50+
}
51+
}
52+
}
53+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using Microsoft.AspNetCore.Http;
2+
using System.Diagnostics;
3+
using System.Threading.Tasks;
4+
5+
namespace FaasNet.Runtime.GetSql.Middlewares
6+
{
7+
public class ResponseMetricMiddleware
8+
{
9+
private readonly RequestDelegate _request;
10+
11+
public ResponseMetricMiddleware(RequestDelegate request)
12+
{
13+
_request = request;
14+
}
15+
16+
public async Task Invoke(HttpContext httpContext, MetricReporter reporter)
17+
{
18+
var path = httpContext.Request.Path.Value;
19+
if (httpContext.Request.Method != HttpMethods.Post)
20+
{
21+
await _request.Invoke(httpContext);
22+
return;
23+
}
24+
25+
26+
var sw = Stopwatch.StartNew();
27+
try
28+
{
29+
await _request.Invoke(httpContext);
30+
}
31+
finally
32+
{
33+
sw.Stop();
34+
reporter.RegisterRequest();
35+
reporter.RegisterResponseTime(httpContext.Response.StatusCode, httpContext.Request.Method, sw.Elapsed);
36+
}
37+
}
38+
}
39+
}
Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
using FaasNet.Runtime.Factories;
2-
using FaasNet.Runtime.Parameters;
2+
using FaasNet.Runtime.GetSql.Middlewares;
33
using Microsoft.AspNetCore.Builder;
44
using Microsoft.AspNetCore.Http;
5+
using Microsoft.Extensions.DependencyInjection;
56
using Newtonsoft.Json;
6-
using System;
7+
using Prometheus;
78
using System.IO;
8-
using System.Net;
9-
using System.Threading.Tasks;
109

1110
namespace FaasNet.Runtime.GetSql
1211
{
1312
public class Startup
1413
{
14+
public void ConfigureServices(IServiceCollection services)
15+
{
16+
services.AddSingleton<MetricReporter>();
17+
}
18+
1519
public void Configure(IApplicationBuilder app)
1620
{
21+
app.UseMetricServer();
1722
app.Map("/configuration", (c) =>
1823
{
1924
c.Run(async (httpContext) =>
@@ -25,38 +30,8 @@ public void Configure(IApplicationBuilder app)
2530
await httpContext.Response.WriteAsync(json);
2631
});
2732
});
28-
app.Use(async (context, next) =>
29-
{
30-
if (context.Request.Method != HttpMethods.Post)
31-
{
32-
await next.Invoke();
33-
return;
34-
}
35-
36-
var functionHandler = new FunctionHandler();
37-
try
38-
{
39-
var requestBody = await GetRequest(context.Request.Body);
40-
var parameter = JsonConvert.DeserializeObject<FunctionParameter<GetSqlConfiguration>>(requestBody);
41-
var result = await functionHandler.Handle(parameter);
42-
context.Response.StatusCode = 200;
43-
context.Response.ContentType = "application/json";
44-
await context.Response.WriteAsync(result.ToString());
45-
}
46-
catch (Exception ex)
47-
{
48-
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
49-
await context.Response.WriteAsync(ex.Message);
50-
}
51-
});
52-
}
53-
54-
private Task<string> GetRequest(Stream inputBody)
55-
{
56-
using (var reader = new StreamReader(inputBody))
57-
{
58-
return reader.ReadToEndAsync();
59-
}
33+
app.UseMiddleware<ResponseMetricMiddleware>();
34+
app.UseMiddleware<FunctionMiddleware>();
6035
}
6136
}
6237
}

0 commit comments

Comments
 (0)