DoctorGPT

DoctorGPT brings GPT into production for error diagnosing!
DoctorGPT 把 GPT 用于生产进行错误诊断!
(Not production ready, yet...)
还未准备好投产,但 。。。
DoctorGPT is a lightweight self-contained binary that monitors your application logs for problems and diagnoses them.
DoctorGPT 是一个轻量级的,自包含的二进制文件,可以监控应用日志中的问题并进行诊断。

Usage

用法

OPENAI_KEY=$YOUR_KEY doctorgpt --logfile="program.log" --configfile="config.yaml" --outdir="~/errors"

DoctorGPT will start tailing program.log (without stopping). For each log line, user-defined parsers triggering a diagnosis event (based on regex variable matches) will generate a diagnosis file (see example below) under directory ~/errors using the triggered log line and all previous log context using the OpenAI API. config.yaml file is used at startup to configure the program.
DoctorGPT 将开始追踪 program.log(不会停止)。对于每一行日志,触发诊断事件(基于正则变量匹配)的用户定义解析器会使用触发的日志行,所有以前的日志上下文和OpenAI API,在~/errors 目录下生成诊断文件(见下例)。config.yaml 文件会在启动时用于配置程序。

CLI flags

客户端参数

  • --logfile (string) log file to tail and monitor
    --logfile (string) 要追踪和监控的日志文件
  • --configfile (string) yaml config file location
    --configfile (string) yaml配置文件位置
  • --outdir (string) diagnosis files directory (created if it does not exist)
    --outdir (string) 诊断文件目录(如果不存在会自动创建)
  • --bundlingtimeoutseconds (int) wait some time for logs to come-in after the triggered line (for multi-line error dumps) (default: 5)
    --bundlingtimeoutseconds (int)等待一段时间,等待触发行后的日志进入(用于多行错误转储)(default: 5
  • --debug (bool) debug logging (default: true)
    --debug (bool)调试日志记录(default: true
  • --buffersize (int) maximum number of log entries per buffer (default: 100)
    --buffersize (int) 每个缓冲区最大日志条目数(default: 100
  • --maxtokens (int) maximum number of tokens allowed in API (default: 8000)
    --maxtokens (int)API允许最大tokens数 (default: 8000)
  • --gptmodel (string) GPT model to use (default: "gpt-4").
    --gptmodel (string) 使用的GPT模型 (default: "gpt-4")。

For list of models see: OpenAI API Models
模型列表请参阅 OpenAI API Models

Configuration

配置

See example yaml documentation:
yaml文档示例查看:

# Prompt to be sent alongside error context to the GPT API
prompt: "You are ErrorDebuggingGPT. Your sole purpose in this world is to help software engineers by diagnosing software system errors and bugs that can occur in any type of computer system. The message following the first line containing \"ERROR:\" up until the end of the prompt is a computer error no more and no less. It is your job to try to diagnose and fix what went wrong. Ready?\nERROR:\n$ERROR"

parsers:

  # Matches line: [1217/201832.950515:ERROR:cache_util.cc(140)] Unable to move cache folder GPUCache to old_GPUCache_000
  - regex: '^\[(\d{4}\/\d{6}\.\d{6}):(?P<LEVEL>\w+):([\w\.\_]+)\(\d+\)\]\s+(?P<MESSAGE>.*)$'

    # Conditions in which the parsed log will trigger a diagnosis
    triggers:
      - variable: "LEVEL"
        regex:    "ERROR"

    # Conditions in which the parsed log will be ignored for triggers
    # To create exceptions which won't trigger the GPT API
    filters:
      - variable: "MESSAGE"
        regex:    "HTTP 401"

    # Conditions in which the parsed log will be ignored and excluded from the API context
    # For sensitive or spammy log entries. These will never be sent to the GPT API
    excludes:
      - variable: "LEVEL"
        regex:    "DEBUG"

  # Matches line:  2022-01-27 21:37:36.776 0x2eb3     Default       511 photolibraryd: PLModelMigration.m:314   Creating sqlite error indicator file
  - regex: '^(?P<DATE>[^ ]+)\s+(?P<TIME>[^ ]+)\s+[^ ]+(?P<LEVEL>[^ ]+)\s+(?P<MESSAGE>.*)$'

  # When more than one trigger is present, just one trigger is sufficient to trigger a diagnosis
    triggers:
      - variable: "LEVEL"
        regex:    "Default"
      - variable: "MESSAGE"
        regex:    "(?i)ERROR:"
    # Filters and excludes were not specified

  # Last parser must always be a generic one that matches any line
  - regex: '^(?P<MESSAGE>.*)$'
    # All filters, triggers and excludes were not specified

Example

示例

This is how the file ::Users::yamilmolinar::error.log:18.diagnosed file looks like:
文件 ::Users::yamilmolinar::error.log:18.diagnosed 内容:

LOG LINE:
/Users/yamilmolinar/error.log:18

BASE PROMPT:
 You are ErrorDebuggingGPT. Your sole purpose in this world is to help software engineers by diagnosing software system errors and bugs that can occur in any type of computer system. The message following the first line containing \"ERROR:\" up until the end of the prompt is a computer error no more and no less. It is your job to try to diagnose and fix what went wrong. Ready?\nERROR:\n$ERROR

CONTEXT:
yarn run v1.22.19
$ tsnd --respawn --transpile-only --no-notify --ignore-watch node_modules src/index.ts
[INFO] 15:20:25 ts-node-dev ver. 2.0.0 (using ts-node ver. 10.8.0, typescript ver. 4.8.4)
[INFO]  DB ready
[INFO]  Auth ready
[INFO]  Apollo setup
[INFO]  Server started at http://localhost:5555/graphql 🚀

Query: Me
POST /graphql 200 241.389 ms - 21

prisma:query SELECT 1
prisma:query SELECT "public"."User"."id", "public"."User"."email", "public"."User"."password", "public"."User"."firstName", "public"."User"."lastName", "public"."User"."avatar", "public"."User"."role", "public"."User"."bio", "public"."User"."createdAt", "public"."User"."updatedAt" FROM "public"."User" WHERE "public"."User"."email" = $2 LIMIT $2 OFFSET $3
[ERROR]  PrismaClientKnownRequestError:
Invalid `prisma.user.findFirst()` invocation in
/Users/yamilmolinar/Repos/boilerplate/packages/api/src/modules/user/user.service.ts:32:36

  29 }
  30
  31 async checkUserExists(where: UserWhereInput) {
→ 32   const user = await prisma.user.findFirst(
The table `public.User` does not exist in the current database.
    at RequestHandler.handleRequestError (/Users/yamilmolinar/Repos/boilerplate/node_modules/@prisma/client/runtime/index.js:30851:13)
    at RequestHandler.request (/Users/yamilmolinar/Repos/boilerplate/node_modules/@prisma/client/runtime/index.js:30834:12)
    at PrismaClient._request (/Users/yamilmolinar/Repos/boilerplate/node_modules/@prisma/client/runtime/index.js:31812:16)
    at UserService.checkUserExists (/Users/yamilmolinar/Repos/boilerplate/packages/api/src/modules/user/user.service.ts:32:18)
    at UserService.register (/Users/yamilmolinar/Repos/boilerplate/packages/api/src/modules/user/user.service.ts:26:5)
    at UserResolver.register (/Users/yamilmolinar/Repos/boilerplate/packages/api/src/modules/user/user.resolver.ts:93:18)
    at dispatchHandler (/Users/yamilmolinar/Repos/boilerplate/node_modules/type-graphql/dist/resolvers/helpers.js:82:24)
    at /Users/yamilmolinar/Repos/boilerplate/node_modules/type-graphql/dist/resolvers/helpers.js:83:26
    at ErrorInterceptor (/Users/yamilmolinar/Repos/boilerplate/packages/api/src/lib/globalMiddleware.ts:29:12)
    at dispatchHandler (/Users/yamilmolinar/Repos/boilerplate/node_modules/type-graphql/dist/resolvers/helpers.js:82:24) {
  code: 'P2021',
  clientVersion: '4.4.0',
  meta: { table: 'public.User' }
}

Mutation: Register
POST /graphql 200 365.616 ms - 2139

DIAGNOSIS:
It seems the error is caused by a missing table in the database. The table `public.User` does not exist in the current database, and this is causing the `PrismaClientKnownRequestError` to be thrown when trying to execute `prisma.user.findFirst()` in the `UserService.checkUserExists()` function.

To resolve this issue, follow these steps:

1. Ensure that you have properly set up your database schema and that the `public.User` table is defined. If it's not, add the necessary schema definition for the User table.

2. Ensure that Prisma is properly configured to connect to your database. Double-check the configuration in your `prisma/schema.prisma` file, and make sure the database URL and other settings are correct.

3. Run a migration to update your actual database's schema. You can do this by running the following command:

npx prisma migrate dev --name init --preview-feature

This command will create the necessary tables in your database based on your Prisma schema file, apply the migration, and generate the Prisma Client.

4. After running the migration, restart your server and test your application again to ensure that the error is resolved.

If you still encounter issues, double-check your Prisma configuration, as well as your database connection settings, and ensure your code logic is correct.

Parser library (to be enhanced)

解析库(待完善)

A library of common log parsers is contained in config.yaml. These parsers were tested against real logs in testlogs/*_2k.log.
config.yaml包含一个常见的日志解析器的库,这些解析器都已根据 testlogs/*_2k.log 里的真实日志进行了测试。

  1. Android
  2. Apache
  3. HDFS
  4. Hadoop
  5. Linux
  6. Mac
  7. Spark
  8. Windows

See parsers_test.go for tests and loghub for more log samples.
测试相关请查看 parsers_test.go,更多日志示例请查看loghub。

Installation

安装

Using go install:
使用 go install:

  • GOBIN=/usr/local/bin go install "github.com/ingyamilmolinar/doctorgpt/agent"

Dependencies

依赖

  1. A Go compiler (for building and running tests only)
    一个GO编译器(仅用于构建和运行测试)
  2. docker (for development)
    docker (用于开发环境)
  3. k3d (for development)
    k3d(用于开发环境)
  4. kubectl (for development)
    kubectl (用于开发环境)
  5. make (for development)
    make (用于开发环境)

Features (to be enhanced)

功能特性(待完善)

  1. Environment independent self-sufficient lightweight (8.3MB) binary. (Windows support is missing but could be easily added)
    独立于环境的自给自足的轻量级(8.3MB)二进制文件。(缺少Windows支持,但可以很容易添加)
  2. Alpine Linux Docker image
    Alpine Linux Docker 镜像
  3. Configurable chatGPT prompt
    可配置的 chatGPT 提示词
  4. Supports every GPT model version
    支持每个 GPT 模型版本
  5. Match multiple log formats within the same file
    匹配同个文件内各种日志格式
  6. Match multiple parsers for the same log entry
    为同个日志条目匹配多个解析器
  7. Match multiple filters for the same log entry
    为同个日志条目匹配多个过滤器
  8. Ignore logs from being part of the context (for sensitive or spammy information)
    忽略作为上下文一部分的日志(用于敏感或垃圾邮件信息)
  9. Support custom variable names
    支持自定义变量名
  10. Powerful regex format (Perl/Go flavor)
    强大的正则表达式格式(Perl/Go风格)
  11. Maximize the amount of log context in the diagnosis
    最大限度地增加诊断中的日志上下文数量

Work in progress

在制品

  1. Dividing log contexts per custom regex match in variable values
    将自定义正则表达式匹配的日志上下文划分为变量值
  2. Enhance library of common log parsers
    完善常见日志解析器库

Future work

今后的工作

  1. Structured logging parsing
    结构化日志分析
  2. Generate a config.yaml based on real life log examples (boottrap config using GPT)
    根据真实日志示例生成config.yaml(使用GPT引导配置)
  3. "FROM scratch" lightweight docker image
    (基于)"FROM scratch" 轻量级docker镜像
  4. Release strategy & CI
    发布策略 & CI
  5. Windows / Mac support
    支持 Windows / Mac 系统
  6. Support custom types (for timestamp comparisons, etc)
    支持自定义类型(用于时间戳比较等)
  7. Production readiness (security, auth, monitoring, optimization, more tests...)
    生产准备就绪(安全,授权,监控,优化,更多测试等)
  8. Sentry SDK integration
    集成 Sentry SDK(一种开源的实时错误跟踪和日志记录平台)
  9. Helm chart
    Helm 图

Development

开发

  • export OPENAI_API=<your-api-key>
  • make k4d-create (to create k3d cluster)
  • make k3d-delete (to delete k3d cluster)
    NOTE: See Makefile for more commands
    注意:更多指令请参阅 Makefile

Testing (Tests do not use OpenAI API)

测试(测试不要使用OpenAI接口 )

  • cd agent; go test ./...; cd -
  • cd agent; go test -v ./...; cd - (verbose mode)

Contributing

捐助

Feel free to open an issue with your suggestion on how to make this program more useful, portable, efficient and production-ready (and of course BUGS!).
关于如何使程序更加有用、轻便、高效和更易于生产(当然还有bugs),可以随时提出你的意见。
Feel free to open MRs. I'll review them if I see they follow the philosophy of this project. For larger chunks of work or design changes, please open an issue first so that the strategy can be discussed.
可以随时打开MR,如果(MR)有遵循这个项目的理念,我会对它们进行审查。对于较大的工作量或设计改动,请先打开一个 issue 以便可以讨论策略。

posted @ 2023-09-16 10:15  505donkey  阅读(94)  评论(0)    收藏  举报