Giter Site home page Giter Site logo

hawkular-client-go's Introduction

Hawkular-Client for Go

Introduction

This client provides abstractions to use the Hawkular REST-endpoints. At this point, only the metrics interface is supported (standalone or part of the distribution). Real world usage can be found for example from the Kubernetes' monitoring project, Heapster and this client is bundled with the Openshift to provide metrics functionality from Hawkular-Metrics.

For further information on available functionality, see the documentation of Hawkular-Metrics.

   Copyright 2015-2016 Red Hat, Inc. and/or its affiliates
   and other contributors.

   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.

Usage

Installation

To install the package, one can use the go command of go get github.com/hawkular/hawkular-client-go.

Basic usage

For examples of usage, see the client_test.go.

Initialization

To create new instance of Hawkular, use the function NewHawkularClient and provide it with the struct Parameters

p := Parameters{Tenant: "default", Url: "http://localhost:8080"}
h := NewHawkularClient(p)

Creating and modifying metric definitions

To create new metric definitions, we need the MetricDefinition struct. The required information is Id and Type, but you can also add tags at the same time. In this example we create a metric called doc.gauge.1 and set some tags to it. You can later alter the tags by using the methods UpdateTags and DeleteTags. The Create function returns two values, first a boolean that indicates if the creation succeeded (it will return false if there’s duplicate id already) and also any potential connection or other errors.

tags := make(map[string]string)
tags["env"] = "documentation-project"

md_tags := MetricDefinition{Id: "doc.gauge.1", Tags: tags, Type: Gauge}
ok, err = c.Create(md_tags)

Fetching the definitions and tags introduces us to the principal concept around the client, which is compositional functions. We can alter the behavior of all the commands in the go-client by giving as input some modifier functions. Fetching the definitions happens with the function Definitions and as parameters we can give it some filters by including them inside the Filters function. For example to get all the Gauge definitions with given tags filter, we would do the following:

mdq, err := c.Definitions(Filters(TypeFilter(Gauge), TagsFilter(tags)))

Writing datapoints

Datapoints are written to the server inside the MetricHeader. You need to create Datapoint struct and set the time and value and embed that datapoint inside a MetricHeader struct. You can write multiple datapoints to a multiple metric ids in a single call to Write().

If the Write() happens to fail with some temporary reason (such as network issue), you can always resend the same request - old values are simply overwritten.

dp := Datapoint{Value: 1.45, Timestamp: time.Now()}

header := MetricHeader{
      ID:   "doc.gauge.1",
      Data: []Datapoint{dp},
      Type: Gauge,
}
err := c.Write([]MetricHeader{header})

For performance reasons, it is recommended to write multiple metrics in one call.

Reading datapoints

Reading datapoints has two approaches, you can either request raw metrics and datapoints that you’ve stored on the server or you can request aggregates / downsampled values. ReadRaw() returns the same datatypes as what was used when writing to the server:

metric, err := c.ReadRaw(Gauge, "doc.gauge.1")

metric should now be equal to what we sent in the previous chapter. We can change the order of returned metrics by giving OrderFilter function inside the Filters function as parameter to the ReadRaw. Default is ascending.

To request aggregated view of the stored metrics, we can use the ReadBuckets() method. The returned struct is Bucketpoint. In the following example we’ll request a single bucket of all the data, data was searched from all the metrics that have env tag with value unittest and we’re interested in calculated percentiles of values 90% and 99%.

tags := make(map[string]string)
tags["env"] = "unittest"

bp, err := c.ReadBuckets(Gauge, Filters(TagsFilter(tags), BucketsFilter(1), PercentilesFilter([]float64{90.0, 99.0})))

Advanced usage

Extending feature set

Client usage is based on the compositional nirvana, overloading the functions with more functions. All the functions are built on top of the Send(), which is accepting functions that are based on the Modifier type.

Base function used to build features
type Modifier func(*http.Request) error

INFO: Don’t forget to check Filter type and Endpoint type as well, which may be better startpoint for URL modifiers.

hawkular-client-go's People

Contributors

burmanm avatar ebaron avatar edwardbetts avatar jmazzitelli avatar jshaughn avatar pilhuhn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hawkular-client-go's Issues

Support raw/query interface

Still in the unstable format, upcoming HWKMETRICS 0.17.0 supports ReadRaw requests with given filters (such as tags) also instead of just id.

Rethink datapoints without floats

Currently the datapoints modify most of the stuff to float64, although Counters use int64 (or uint64?) instead. Think about this with the API stability.

Admin token is not supported

In standalone deployment, tenants endpoint requires Hawkular-Admin-Token header. This isn't currently supported natively in the Go client (can be overridden with a new function though)

Support opentracing

It would be cool if the client can also support opentracing. This would allow go apps to send traces to hawkular.

Documentation Incorrect on go get

The README states to use:

go get "github.com/hawkular/hawkular-client-go"

when you actually have to use:

go get "github.com/hawkular/hawkular-client-go/metrics"

support Basic auth

in client.go I see this:
if len(c.Token) > 0 {
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", c.Token))

This supports Bearer tokens. But no support for Basic auth.

We should add a "Username" and "Password" in the Parameters object. If they are specified, then add a "Basic" header. If they are not specified, but token is, then do what we are already doing (add a Bearer header). If neither are specified, do nothing.

tags in datapoints were missing

If creating metric definition with tags then write data points with tags, tags shown in the GET query. When not creating metric definition, only write data points, tags defined inside data points were all missing in the GET query returned results.

For example

tags := make(map[string]string)
tags["env"] = "hawkular"

dp := metrics.Datapoint{Value: 1.45, Timestamp: time.Now(), Tags: tags}

header := metrics.MetricHeader{
   ID:   "doc.gauge.1",
   Data: []metrics.Datapoint{dp},
   Type: metrics.Gauge,
}
err = c.Write([]metrics.MetricHeader{header})

Do I always have to write both MetricDefinition and MetricHeader? Can tags in MetricDefinition different than tags in the data points?

My another question is if this client is still usable? thanks.

DeleteTags doesn't work if tag values have spaces in them

The signature for DeleteTags is:

// DeleteTags deletes given tags from the definition
func (c *Client) DeleteTags(t MetricType, id string, tags map[string]string, o ...Modifier) error {

Why does it take a map[string]string? You delete tags by name; the value is irrelevent. However, it looks like the code actually builds the DELETE URL with the values which is probably why I'm gettting a error when I try to delete tags:

o = prepend(o, c.URL("DELETE", TypeEndpoint(t), SingleMetricEndpoint(id), TagEndpoint(), TagsEndpoint(tags)))
r, err := c.Send(o...)

This method should only take a slice of strings (the tag names):

// DeleteTags deletes given tags from the definition
func (c *Client) DeleteTags(t MetricType, id string, tags []string, o ...Modifier) error {

Or if you don't want to change the signature, just have the code ignore the values and just take the keys of "tags"

Encoding of ID in GET URL is wrong for spaces

I had a space in my metric ID. Some of the APIs were not working (it was saying the metric didn't exist when it did, for example).

I believe the problem is here:

https://github.com/hawkular/hawkular-client-go/blob/master/metrics/client.go#L697

// SingleMetricEndpoint is a URL endpoint for requesting single metricID
func SingleMetricEndpoint(id string) Endpoint {
    return func(u *url.URL) {
        addToURL(u, url.QueryEscape(id))  // <----- look here!
    }
}

This is using "QueryEscape" which is for escaping strings for use in the query string portion of a URL - NOT within a path - but unfortunately, it is being used to encode path strings as in here:

https://github.com/hawkular/hawkular-client-go/blob/master/metrics/client.go#L336

// . But this is used for escaping strings for use in a path, lDefinition returns a single metric definition
func (c *Client) Definition(t MetricType, id string, o ...Modifier) (*MetricDefinition, error) {
    o = prepend(o, c.URL("GET", TypeEndpoint(t), SingleMetricEndpoint(id)))

Which is the place where I was seeing my error. I had a metric Id like "My Metric ID", which gets encoded as "My+Metric+ID". The GET URL that gets built here looked like this:

http://192.168.1.15:8080/hawkular/metrics/counters/My+Metric+ID

This causes the lookup to not find my metric even though it exists. If I change the code such that the URL used %20 instead of + for the space encoding, it worked and my metric was found:

http://192.168.1.15:8080/hawkular/metrics/counters/My%20Metric%20ID

My quick and dirty code change that saw it work by encoding with %20 was:

// SingleMetricEndpoint is a URL endpoint for requesting single metricID
func SingleMetricEndpoint(id string) Endpoint {
    return func(u *url.URL) {
        escaped := url.QueryEscape(id)
        escaped = strings.Replace(escaped, "+", "%20", -1) // <-- replace the + with %20
        addToURL(u, escaped)
    }
}

Create documentation

Golang client is in need of a documentation with some samples on how to use the client.

Provide new DeleteTags function that only requires tag names

The signature for DeleteTags is:

// DeleteTags deletes given tags from the definition
func (c *Client) DeleteTags(t MetricType, id string, tags map[string]string, o ...Modifier) error {

It takes a map[string]string because that is what the older H-Metrics API required (earlier than version 0.15.0). But in 0.15.0 and after, H-Metrics allows you to delete tags simply by name without giving their values - see https://issues.jboss.org/browse/HWKMETRICS-385. So we should provide a new method that only takes a slice of strings (the tag names):

// DeleteTags deletes given tags from the definition
func (c *Client) DeleteTagsByName(t MetricType, id string, tags []string, o ...Modifier) error {

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.