123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- // Copyright 2015 Google Inc. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- // Client library to programmatically access cAdvisor API.
- package v2
- import (
- "bytes"
- "encoding/json"
- "fmt"
- "io/ioutil"
- "net/http"
- "net/url"
- "path"
- "strconv"
- "strings"
- v1 "github.com/google/cadvisor/info/v1"
- "github.com/google/cadvisor/info/v2"
- )
- // Client represents the base URL for a cAdvisor client.
- type Client struct {
- baseUrl string
- }
- // NewClient returns a new client with the specified base URL.
- func NewClient(url string) (*Client, error) {
- if !strings.HasSuffix(url, "/") {
- url += "/"
- }
- return &Client{
- baseUrl: fmt.Sprintf("%sapi/v2.1/", url),
- }, nil
- }
- // MachineInfo returns the JSON machine information for this client.
- // A non-nil error result indicates a problem with obtaining
- // the JSON machine information data.
- func (self *Client) MachineInfo() (minfo *v1.MachineInfo, err error) {
- u := self.machineInfoUrl()
- ret := new(v1.MachineInfo)
- if err = self.httpGetJsonData(ret, nil, u, "machine info"); err != nil {
- return
- }
- minfo = ret
- return
- }
- // MachineStats returns the JSON machine statistics for this client.
- // A non-nil error result indicates a problem with obtaining
- // the JSON machine information data.
- func (self *Client) MachineStats() ([]v2.MachineStats, error) {
- var ret []v2.MachineStats
- u := self.machineStatsUrl()
- err := self.httpGetJsonData(&ret, nil, u, "machine stats")
- return ret, err
- }
- // VersionInfo returns the version info for cAdvisor.
- func (self *Client) VersionInfo() (version string, err error) {
- u := self.versionInfoUrl()
- version, err = self.httpGetString(u, "version info")
- return
- }
- // Attributes returns hardware and software attributes of the machine.
- func (self *Client) Attributes() (attr *v2.Attributes, err error) {
- u := self.attributesUrl()
- ret := new(v2.Attributes)
- if err = self.httpGetJsonData(ret, nil, u, "attributes"); err != nil {
- return
- }
- attr = ret
- return
- }
- // Stats returns stats for the requested container.
- func (self *Client) Stats(name string, request *v2.RequestOptions) (map[string]v2.ContainerInfo, error) {
- u := self.statsUrl(name)
- ret := make(map[string]v2.ContainerInfo)
- data := url.Values{
- "type": []string{request.IdType},
- "count": []string{strconv.Itoa(request.Count)},
- "recursive": []string{strconv.FormatBool(request.Recursive)},
- }
- u = fmt.Sprintf("%s?%s", u, data.Encode())
- if err := self.httpGetJsonData(&ret, nil, u, "stats"); err != nil {
- return nil, err
- }
- return ret, nil
- }
- func (self *Client) machineInfoUrl() string {
- return self.baseUrl + path.Join("machine")
- }
- func (self *Client) machineStatsUrl() string {
- return self.baseUrl + path.Join("machinestats")
- }
- func (self *Client) versionInfoUrl() string {
- return self.baseUrl + path.Join("version")
- }
- func (self *Client) attributesUrl() string {
- return self.baseUrl + path.Join("attributes")
- }
- func (self *Client) statsUrl(name string) string {
- return self.baseUrl + path.Join("stats", name)
- }
- func (self *Client) httpGetResponse(postData interface{}, urlPath, infoName string) ([]byte, error) {
- var resp *http.Response
- var err error
- if postData != nil {
- data, marshalErr := json.Marshal(postData)
- if marshalErr != nil {
- return nil, fmt.Errorf("unable to marshal data: %v", marshalErr)
- }
- resp, err = http.Post(urlPath, "application/json", bytes.NewBuffer(data))
- } else {
- resp, err = http.Get(urlPath)
- }
- if err != nil {
- return nil, fmt.Errorf("unable to post %q to %q: %v", infoName, urlPath, err)
- }
- if resp == nil {
- return nil, fmt.Errorf("received empty response for %q from %q", infoName, urlPath)
- }
- defer resp.Body.Close()
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- err = fmt.Errorf("unable to read all %q from %q: %v", infoName, urlPath, err)
- return nil, err
- }
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("request %q failed with error: %q", urlPath, strings.TrimSpace(string(body)))
- }
- return body, nil
- }
- func (self *Client) httpGetString(url, infoName string) (string, error) {
- body, err := self.httpGetResponse(nil, url, infoName)
- if err != nil {
- return "", err
- }
- return string(body), nil
- }
- func (self *Client) httpGetJsonData(data, postData interface{}, url, infoName string) error {
- body, err := self.httpGetResponse(postData, url, infoName)
- if err != nil {
- return err
- }
- if err = json.Unmarshal(body, data); err != nil {
- err = fmt.Errorf("unable to unmarshal %q (Body: %q) from %q with error: %v", infoName, string(body), url, err)
- return err
- }
- return nil
- }
|