Exceptionless
ExceptionLess是一个开源免费的实时日志收集框架,内置日志分类看板, 支持 Web hook 发送异常通知。
安装
exceptionless.yaml :
apiVersion: apps/v1
kind: Deployment
metadata:
name: exceptionless-api
namespace: default
labels:
tag: exceptionless-api
spec:
replicas: 1
selector:
matchLabels:
app: exceptionless-api
template:
metadata:
labels:
app: exceptionless-api
spec:
containers:
- name: exceptionless-api
image: "exceptionless/api:6.0.0"
imagePullPolicy: IfNotPresent
env:
- name: EX_AppMode
value: "Production"
- name: EX_BaseURL
value: http://localhost:30013
- name: EX_ConnectionStrings__Cache
value: provider=redis
- name: EX_ConnectionStrings__Elasticsearch
value: server=http://elasticsearch:9200;enable-size-plugin=false
#- name: EX_ConnectionStrings__Email
# value: smtps://user:password@smtp.host.com:587
- name: EX_ConnectionStrings__MessageBus
value: provider=redis
- name: EX_ConnectionStrings__Queue
value: provider=redis
- name: EX_ConnectionStrings__Redis
value: server=redis,abortConnect=false
- name: EX_ConnectionStrings__Storage
value: provider=folder;path=/app/storage
- name: EX_RunJobsInProcess
value: 'false'
volumeMounts:
- mountPath: "/app/storage"
name: exceptionless-storage
ports:
- containerPort: 80
resources:
limits:
cpu: 1000m
memory: 2048Mi
requests:
cpu: 100m
memory: 128Mi
terminationGracePeriodSeconds: 10
volumes:
- name: exceptionless-storage
hostPath:
path: "/g/k8s/volumes/exceptionless"
type: DirectoryOrCreate
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: exceptionless-api
namespace: default
labels:
tag: "exceptionless-api"
spec:
type: NodePort
ports:
- nodePort: 30012
port: 80
targetPort: 80
protocol: TCP
selector:
app: exceptionless-api
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: exceptionless-job
namespace: default
labels:
tag: exceptionless-job
spec:
replicas: 1
selector:
matchLabels:
app: exceptionless-job
template:
metadata:
labels:
app: exceptionless-job
spec:
containers:
- name: exceptionless-job
image: "exceptionless/job:6.0.0"
imagePullPolicy: IfNotPresent
env:
- name: EX_AppMode
value: "Production"
- name: EX_BaseURL
value: http://localhost:30013
- name: EX_ConnectionStrings__Cache
value: provider=redis
- name: EX_ConnectionStrings__Elasticsearch
value: server=http://elasticsearch:9200;enable-size-plugin=false
#- name: EX_ConnectionStrings__Email
# value: smtps://user:password@smtp.host.com:587
- name: EX_ConnectionStrings__MessageBus
value: provider=redis
- name: EX_ConnectionStrings__Queue
value: provider=redis
- name: EX_ConnectionStrings__Redis
value: server=redis,abortConnect=false
- name: EX_ConnectionStrings__Storage
value: provider=folder;path=/app/storage
- name: EX_RunJobsInProcess
value: 'false'
volumeMounts:
- mountPath: "/app/storage"
name: exceptionless-job-storage
ports:
- containerPort: 80
resources:
limits:
cpu: 1000m
memory: 2048Mi
requests:
cpu: 100m
memory: 128Mi
terminationGracePeriodSeconds: 10
volumes:
- name: exceptionless-job-storage
hostPath:
path: "/g/k8s/volumes/exceptionless"
type: DirectoryOrCreate
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: exceptionless-job
namespace: default
labels:
tag: "exceptionless-job"
spec:
type: NodePort
ports:
- nodePort: 30014
port: 80
targetPort: 80
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: exceptionless-ui
namespace: default
labels:
tag: exceptionless-ui
spec:
replicas: 1
selector:
matchLabels:
app: exceptionless-ui
template:
metadata:
labels:
app: exceptionless-ui
spec:
containers:
- name: exceptionless-ui
image: "exceptionless/ui:2.8.1497"
imagePullPolicy: IfNotPresent
env:
- name: AppMode
value: "Production"
- name: EX_ApiUrl
value: http://localhost:30012
ports:
- containerPort: 80
resources:
limits:
cpu: 1000m
memory: 2048Mi
requests:
cpu: 100m
memory: 128Mi
terminationGracePeriodSeconds: 10
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: exceptionless-ui
namespace: default
labels:
tag: "exceptionless-ui"
spec:
type: NodePort
ports:
- nodePort: 30013
port: 80
targetPort: 80
protocol: TCP
selector:
app: exceptionless-ui
需要注意的是:api 的存储目录需要和 job 的存储目录相同。
安装完成后通过 ui 定义的端口 http://localhost:30013/ 访问 exceptionless 。
创建账号登录后,创建组织及项目:
创建项目后,可获得项目秘钥:
客户端使用此秘钥可以向 exceptionless 推送数据。
代码集成
引用以下包 :
Exceptionless.AspNetCore
Exceptionless.Extensions.Logging
exceptionless 配置:
"exceptionless": {
"ApiKey": "3bGO3KepPiN6GxDMGY2omwXn4RjJpruvz72xI2Pg",
"ServerUrl": "http://localhost:30012"
}
Program 中绑定 exceptionless 配置:
public class Program
{
public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
.AddEnvironmentVariables()
.Build();
public static int Main(string[] args)
{
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(Configuration)
.MinimumLevel.Debug()
.Enrich.FromLogContext()
.WriteTo.Console(new RenderedCompactJsonFormatter())
.CreateLogger();
Configuration.GetSection("exceptionless").Bind(Exceptionless.ExceptionlessClient.Default.Configuration);
try
{
Log.Information("Starting web host");
CreateHostBuilder(args).Build().Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
...
}
启用 exceptionless 中间件 ,注意在所有中间件之前注册,以达到捕获全局异常的目的:
app.UseExceptionless();