在第一次接觸這個 Cortex 的時候,必須認可,筆者在網上能找到的資料甚少,逼着筆者一點一點的看官網,真的是受不了了。這裏,筆者重點講一下,官網API中的筆者遇到的一些坑,以及咱們去使用這些API。 目前筆者在網上找到的資料基本都是介紹 Cortex 和 Prometheus 的多租戶,要麼是講原理,並且原理仍是官網上的。因此這裏簡單的去介紹下Cortex 裏面幾個API。
<!--more-->git
在官網上,提供了一下幾種 API Remote API / Alerts & Rules API / Configs API / Endpoints / Manage Rules . 這裏呢,我只說這裏的 RemoteAPI . github
咱們先看一下這個 Remote API :golang
寫的很詳細,目前是算比較詳細的,筆者在一開始看的時候就幾行,第一行:支持Prometheus 的 remote_read / remote_write , 第二行 , 對於Http post 裏面的請求體首先是 Protocol Buffers , 再來一個 snappy . 第三行是 遠程讀寫 api . 目前來看是又修改了下。並且咱們也能看到,當前的這個 Cortex 的APIS 正在編寫中。shell
這裏的 remote api 官網講了兩個,這兩個對應着的是 Prometheus 中的 remote_write / remote_read . 這裏對這兩個作個簡單的介紹,筆者這裏也主要用到了的 remote_write .segmentfault
剛剛說了,這裏的 remote_write 對應着的是 Prometheus 裏面的那個 remote_write .因此呢,咱們如今須要到 Prometheus 裏面看看這個remote_write 的基本配置是什麼樣的。api
咱們進入到Prometheus 的官網,去看一下。 我這裏不貼所有的,所有的你們去官網查看就好:服務器
# The URL of the endpoint to send samples to. url: <string> # Timeout for requests to the remote write endpoint. [ remote_timeout: <duration> | default = 30s ] # List of remote write relabel configurations. write_relabel_configs: [ - <relabel_config> ... ] # Sets the `Authorization` header on every remote write request with the # configured username and password. # password and password_file are mutually exclusive. basic_auth: [ username: <string> ] [ password: <string> ] [ password_file: <string> ] # Sets the `Authorization` header on every remote write request with # the configured bearer token. It is mutually exclusive with `bearer_token_file`. [ bearer_token: <string> ] # Sets the `Authorization` header on every remote write request with the bearer token # read from the configured file. It is mutually exclusive with `bearer_token`. [ bearer_token_file: /path/to/bearer/token/file ] # Configures the remote write request's TLS settings. tls_config: [ <tls_config> ] # Optional proxy URL. [ proxy_url: <string> ]
這裏的配置,寫的很清楚,這裏筆者用到的主要是兩個配置,一個是 url , 一個是 basic_auth ,你們能夠參考我以前的一個文章使用Cortex實現Prometheus的多租戶管理 . 很簡單的一個remote_write 。架構
若是你覺得,我這就完了,那你就錯了。我這裏講的是 Cortex 裏面的查詢的 APIs , 這裏的幾個API 目前官網我還沒看到,也多是由於我沒找到吧。app
這裏呢,不必去跟你們介紹每個API。你們看一下這個API接口就清楚了:ide
// API provides bindings for Prometheus's v1 API. type API interface { // Alerts returns a list of all active alerts. Alerts(ctx context.Context) (AlertsResult, error) // AlertManagers returns an overview of the current state of the Prometheus alert manager discovery. AlertManagers(ctx context.Context) (AlertManagersResult, error) // CleanTombstones removes the deleted data from disk and cleans up the existing tombstones. CleanTombstones(ctx context.Context) error // Config returns the current Prometheus configuration. Config(ctx context.Context) (ConfigResult, error) // DeleteSeries deletes data for a selection of series in a time range. DeleteSeries(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) error // Flags returns the flag values that Prometheus was launched with. Flags(ctx context.Context) (FlagsResult, error) // LabelNames returns all the unique label names present in the block in sorted order. LabelNames(ctx context.Context) ([]string, api.Warnings, error) // LabelValues performs a query for the values of the given label. LabelValues(ctx context.Context, label string) (model.LabelValues, api.Warnings, error) // Query performs a query for the given time. Query(ctx context.Context, query string, ts time.Time) (model.Value, api.Warnings, error) // QueryRange performs a query for the given range. QueryRange(ctx context.Context, query string, r Range) (model.Value, api.Warnings, error) // Series finds series by label matchers. Series(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]model.LabelSet, api.Warnings, error) // Snapshot creates a snapshot of all current data into snapshots/<datetime>-<rand> // under the TSDB's data directory and returns the directory as response. Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, error) // Rules returns a list of alerting and recording rules that are currently loaded. Rules(ctx context.Context) (RulesResult, error) // Targets returns an overview of the current state of the Prometheus target discovery. Targets(ctx context.Context) (TargetsResult, error) // TargetsMetadata returns metadata about metrics currently scraped by the target. TargetsMetadata(ctx context.Context, matchTarget string, metric string, limit string) ([]MetricMetadata, error) }
看到這個是否是就很好理解了?
咱們在使用的時候,首先須要先知道一個結構體:
type Client struct { alertmanagerClient promapi.Client distributorAddress string timeout time.Duration httpClient *http.Client querierClient promv1.API orgID string }
能夠看到,在這個 Client 裏面,有幾個client , alertmanagerClient / httpClient / querierClient . 先不要好奇爲何會有這麼多的 client . 這裏的每個 client 對應着的都不同。這裏會涉及到Cortex 的微服務的架構問題,這個咱們後期再說。我這裏先說怎麼使用 API 作查詢。 以及咱們的 Push 。
func NewClient(distributorAddress string, querierAddress string, alertmanagerAddress string, orgID string) (*Client, error) { // Create querier API client querierAPIClient, err := promapi.NewClient(promapi.Config{ Address: "http://" + querierAddress + "/api/prom", RoundTripper: &addOrgIDRoundTripper{orgID: orgID, next: http.DefaultTransport}, }) if err != nil { return nil, err } c := &Client{ distributorAddress: distributorAddress, timeout: 5 * time.Second, httpClient: &http.Client{}, querierClient: promv1.NewAPI(querierAPIClient), orgID: orgID, } return c, nil }
咱們先獲得一個 client , 這裏的 promv1 是包 "github.com/prometheus/client_golang/api/prometheus/v1" .
// Query runs a query func (c *Client) Query(query string, ts time.Time) (model.Value, error) { value, _, err := c.querierClient.Query(context.Background(), query, ts) return value, err }
這樣就行了。
這裏的 Push ,就是發送數據到 Cortex 裏面的。Client 用咱們以前拿到的那個 Client
// Push the input timeseries to the remote endpoint func (c *Client) Push(timeseries []prompb.TimeSeries) (*http.Response, error) { // Create write request data, err := proto.Marshal(&prompb.WriteRequest{Timeseries: timeseries}) if err != nil { return nil, err } // Create HTTP request compressed := snappy.Encode(nil, data) req, err := http.NewRequest("POST", fmt.Sprintf("http://%s/api/prom/push", c.distributorAddress), bytes.NewReader(compressed)) if err != nil { return nil, err } req.Header.Add("Content-Encoding", "snappy") req.Header.Set("Content-Type", "application/x-protobuf") req.Header.Set("X-Prometheus-Remote-Write-Version", "0.1.0") req.Header.Set("X-Scope-OrgID", c.orgID) ctx, cancel := context.WithTimeout(context.Background(), c.timeout) defer cancel() // Execute HTTP request res, err := c.httpClient.Do(req.WithContext(ctx)) if err != nil { return nil, err } defer res.Body.Close() return res, nil }
其實就是一個客戶端在往服務器裏面寫數據的過程。
固然了,上面的程序都是有的。你們能夠到 cortex 的源程序裏面找到 , github 的速度很慢,你們能夠到 這個地方去看 cortex
你們能夠克隆到本身本地:
git clone https://gitee.com/sun-iot/cortex.git
在裏面咱們能夠找到這個 Cortex 的幾個隱藏的 API。