Cursor - 人工智能编写代码的强大之处

本文最后更新于:2023年4月27日 晚上

描述

最近需要写一个告警的功能,本来是打算自己实现 metric 和 alert,但是由于我们本来就已经有 grafana 和 prometheus 了,就想要借助成熟体系来实现,这样可以节省很多工作,但是找了一些库,都没有合适的姿势入场,最近主管推给我一个软件 Cursor,来试一下。

使用

  • 先来看下主界面
  • command + k
  • 来试一下
  • 效果
  • 很好,但是好像没有鉴权 [ command + a & command + k ]
  • ok,文件太长就不截图了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    package main

    // Import necessary packages
    import (
    "context"
    "crypto/tls"
    "fmt"
    "net"
    "net/http"
    "time"

    "github.com/prometheus/client_golang/api"
    v1 "github.com/prometheus/client_golang/api/prometheus/v1"
    "github.com/prometheus/common/model"
    )

    // BasicAuthRoundTripper is a RoundTripper that adds basic authentication credentials to requests
    type BasicAuthRoundTripper struct {
    Username string
    Password string
    RoundTripper http.RoundTripper
    }

    func (rt *BasicAuthRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
    req.SetBasicAuth(rt.Username, rt.Password)
    return rt.RoundTripper.RoundTrip(req)
    }

    // Define a struct to hold the query results
    type QueryResult struct {
    Metric model.Metric `json:"metric"`
    Value model.SampleValue `json:"value"`
    }

    // Define a function to query Prometheus with a given username, password
    func QueryPrometheus(username string, password string, query string) ([]QueryResult, error) {
    // Create a new HTTP client with the given username and password
    client, err := api.NewClient(api.Config{
    Address: "http://localhost:9090",
    RoundTripper: &BasicAuthRoundTripper{
    Username: username,
    Password: password,
    RoundTripper: &http.Transport{
    Proxy: http.ProxyFromEnvironment,
    TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    // Set the username and password for basic authentication
    // Note: this is not secure and should not be used in production
    // Instead, use a secure authentication method such as OAuth2
    // or a reverse proxy with authentication
    DialContext: (&net.Dialer{
    Timeout: 30 * time.Second,
    KeepAlive: 30 * time.Second,
    }).DialContext,
    ForceAttemptHTTP2: true,
    MaxIdleConns: 100,
    IdleConnTimeout: 90 * time.Second,
    TLSHandshakeTimeout: 10 * time.Second,
    ExpectContinueTimeout: 1 * time.Second,
    ProxyConnectHeader: http.Header{},
    },
    },
    })
    if err != nil {
    return nil, err
    }

    // Create a new Prometheus API client
    prometheusClient := v1.NewAPI(client)

    // Query Prometheus with the built query string
    result, warnings, err := prometheusClient.Query(context.Background(), query, time.Now())
    if err != nil {
    return nil, err
    }
    if len(warnings) > 0 {
    fmt.Println("Warnings:", warnings)
    }

    // Parse the query result into a slice of QueryResult structs
    var queryResults []QueryResult
    for _, res := range result.(model.Vector) {
    queryResults = append(queryResults, QueryResult{
    Metric: res.Metric,
    Value: res.Value,
    })
    }

    return queryResults, nil
    }
  • 感觉还是不够,如果能按照 label 查询就更好了。
  • 结果如下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    package main

    // Import necessary packages
    import (
    "context"
    "crypto/tls"
    "fmt"
    "net"
    "net/http"
    "time"

    "github.com/prometheus/client_golang/api"
    v1 "github.com/prometheus/client_golang/api/prometheus/v1"
    "github.com/prometheus/common/model"
    )

    // BasicAuthRoundTripper is a RoundTripper that adds basic authentication credentials to requests
    type BasicAuthRoundTripper struct {
    Username string
    Password string
    RoundTripper http.RoundTripper
    }

    func (rt *BasicAuthRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
    req.SetBasicAuth(rt.Username, rt.Password)
    return rt.RoundTripper.RoundTrip(req)
    }

    // Define a struct to hold the query results
    type QueryResult struct {
    Metric model.Metric `json:"metric"`
    Value model.SampleValue `json:"value"`
    }

    // Define a function to query Prometheus with a given username, password, and label
    func QueryPrometheus(username string, password string, my_metric string, key string, value string) ([]QueryResult, error) {
    // Create a new HTTP client with the given username and password
    client, err := api.NewClient(api.Config{
    Address: "http://localhost:9090",
    RoundTripper: &BasicAuthRoundTripper{
    Username: username,
    Password: password,
    RoundTripper: &http.Transport{
    Proxy: http.ProxyFromEnvironment,
    TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    // Set the username and password for basic authentication
    // Note: this is not secure and should not be used in production
    // Instead, use a secure authentication method such as OAuth2
    // or a reverse proxy with authentication
    DialContext: (&net.Dialer{
    Timeout: 30 * time.Second,
    KeepAlive: 30 * time.Second,
    }).DialContext,
    ForceAttemptHTTP2: true,
    MaxIdleConns: 100,
    IdleConnTimeout: 90 * time.Second,
    TLSHandshakeTimeout: 10 * time.Second,
    ExpectContinueTimeout: 1 * time.Second,
    ProxyConnectHeader: http.Header{},
    },
    },
    })
    if err != nil {
    return nil, err
    }

    // Create a new Prometheus API client
    prometheusClient := v1.NewAPI(client)

    // Build the query string with the given label
    query := fmt.Sprintf(`%s{%s="%s"}`, my_metric, key, value)

    // Query Prometheus with the built query string
    result, warnings, err := prometheusClient.Query(context.Background(), query, time.Now())
    if err != nil {
    return nil, err
    }
    if len(warnings) > 0 {
    fmt.Println("Warnings:", warnings)
    }

    // Parse the query result into a slice of QueryResult structs
    var queryResults []QueryResult
    for _, res := range result.(model.Vector) {
    queryResults = append(queryResults, QueryResult{
    Metric: res.Metric,
    Value: res.Value,
    })
    }

    return queryResults, nil
    }
    很好,感觉自己要失业了。

文中有一些代码被我改过,因为最开始生成的代码已经找不到了。

总结

其实 AI 现在已经被训练的非常强大了,无论是 chatGPT 还是其衍生产物,俨然已经成为大势所趋,在未来越快接受并能融入生活进行使用的人,就越能走在时代的前沿,不过回归 Cursor 本身而言,并不是所有生成的代码都可以拿来使用,有一些包可能已经更新了,一些结构已经不存在了,这个时候只需要让他换一个包,或者换一种方式实现就可以了,工具本身灵活度不够,只要人足够灵活,那么使用起来自然就可以千人千面,另外,这个版本每天有使用次数限制,超出使用次数是要收费的,pro 要 $20 一个月,还是挺贵的。


Cursor - 人工智能编写代码的强大之处
https://agopher.com/2023/04/27/tech/2023_cursor_prometheus/
作者
冷宇生(Allen)
发布于
2023年4月27日
更新于
2023年4月27日
许可协议