Git Product home page Git Product logo

ubbagent's Introduction

Metering agent

This metering agent simplifies usage metering of applications and can be used as part of a usage-based billing strategy. It performs the following functions:

  • Accepts usage reports from a local source, such as an application processing requests
  • Aggregates that usage and persists it across restarts
  • Forwards usage to one or more endpoints, retrying in the case of failures

Build and run

git clone https://github.com/GoogleCloudPlatform/ubbagent.git
cd ubbagent
make setup deps build
bin/ubbagent --help

Build and run with bazel

The BUILD.bazel files can be regenerated with:

bazel run //:gazelle

To update WORKSPACE go_repository rules from a go.mod file:

bazel run //:gazelle -- update-repos -from_file=go.mod

To build, test and run with bazel:

bazel build ...
bazel test ...
bazel run ubbagent

Configuration

# The identity section contains authentication information used by the agent.
identities:
- name: gcp
  gcp:
    # A base64-encoded service account key used to report usage to
    # Google Service Control.
    encodedServiceAccountKey: [base64-encoded key]

# The metrics section defines the metric names and types that the agent
# is configured to record.
metrics:
- name: requests
  type: int

  # The endpoints section of a metric defines which endpoints the metric data is sent to.
  endpoints:
  - name: on_disk
  - name: servicecontrol

  # The aggregation section indicates that reports that the agent receives for this metric should
  # be aggregated for a specified period of time prior to being sent to the reporting endpoint.
  aggregation:
    bufferSeconds: 60

- name: instance-seconds
  type: int
  # The empty passthrough second indicates that no aggregation should occur for this metric.
  # Reports received are immediately sent to the reporting endpoint.
  passthrough: {}
  endpoints:
  - name: on_disk
  - name: servicecontrol

# The endpoints section defines where metering data is ultimately sent. Currently
# supported endpoints include:
# * disk - some directory on the local filesystem
# * servicecontrol - Google Service Control: https://cloud.google.com/service-control/overview
endpoints:
- name: on_disk
  disk:
    reportDir: /var/ubbagent/reports
    expireSeconds: 3600
- name: servicecontrol
  servicecontrol:
    identity: gcp
    serviceName: some-service-name.myapi.com
    consumerId: project:<project_id>

# The sources section lists metric data sources run by the agent itself. The currently-supported
# source is 'heartbeat', which sends a defined value to a metric at a defined interval.
sources:
- name: instance-seconds
  heartbeat:
    metric: instance-seconds
    intervalSeconds: 60
    value:
      int64Value: 60
    labels:
      auto: true

Running

To run the agent, provide the following:

  • A local TCP port (for the agent's HTTP daemon)
  • The path to the agent's YAML config file
  • The path to a directory used to store state
  • Optional logging parameters supported by glog (See -logtostderr and -v below)
ubbagent --config path/to/config.yaml --state-dir path/to/state \
         --local-port 3456 -logtostderr -v 2

Usage

The agent provides a local HTTP instance for interaction with metered software. An example curl command to post a report:

curl -X POST -d "{\"name\": \"requests\", \"startTime\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\", \"endTime\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\", \"value\": { \"int64Value\": 10 }, \"labels\": { \"foo\": \"bar2\" } }" 'http://localhost:3456/report'

The agent also provides status indicating its ability to send data to endpoints.

curl http://localhost:3456/status
{
  "lastReportSuccess": "2017-10-04T10:06:15.820953439-07:00",
  "currentFailureCount": 0,
  "totalFailureCount": 0
}

Design

See DESIGN.md.

Kubernetes

The easiest way to deploy the metering agent into a Kubernetes cluster is as a sidecar container alongside the software being metered. A Dockerfile is provided that builds such a container. It accepts the following parameters as environment variables:

  • AGENT_CONFIG_FILE - Required. The path to a file containing the agent's configuration.
  • AGENT_STATE_DIR - Optional. The path under which the agent stores state. If this parameter is not specified, no state will be stored.
  • AGENT_LOCAL_PORT - Optional. The pod-local port on which the agent's HTTP API will listen for reports and provide status. If this parameter is not specified, the agent will not start its HTTP server.

The configuration file is run through envsubst, so it can contain any additional parameters as well. For example, a service account key and a servicecontrol consumerId may be stored in a Kubernetes secret and passed in as environment variables.

ubbagent's People

Contributors

brendanlundy avatar deustis avatar gibbleyg avatar huyhg avatar jvolkman avatar lucacome avatar trironkk avatar vcanaa avatar wgrzelak avatar zhangchizju2012 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ubbagent's Issues

Additional way of configuration Keys and Ids.

The current implementation of ubbagent is requiring to provide a configuration via JSON config.

Unfortunately, marketplace-k8s-app-tools default deployer is providing encodedServiceAccountKey, consumerId etc as Kubernets secrets.
K8s secrets can be mounted into Pod as File or as ENV vars. To make consumers live easy, it would nice to have another way of providing encodedServiceAccountKey and Ids into ubbagent library.
Something Keys/Secrets files path or knows ENV vars.
Similar to https://github.com/golang/oauth2/blob/ef147856a6ddbb60760db74283d2424e98c87bff/google/default.go#L43

Error: identity: too many service account keys

In order to add workaround fix for #39
I'm Parsing config with ubbconfig.Parse, then modify it and json.Marshall it back.
This is a modified json

{
	"identities": [{
		"name": "gcp",
		"gcp": {
			"serviceAccountKey": null,
			"encodedServiceAccountKey": "base64 string"
		}
	}],
	"metrics": [{
		"Name": "nodes",
		"Type": "int",
		"endpoints": [{
			"name": "on_disk"
		}, {
			"name": "servicecontrol"
		}],
		"aggregation": {
			"bufferSeconds": 60
		},
		"passthrough": null
	}],
	"endpoints": [{
		"name": "on_disk",
		"disk": {
			"reportDir": "/tmp/ubbagent/reports",
			"expireSeconds": 3600
		},
		"servicecontrol": null,
		"pubsub": null
	}, {
		"name": "servicecontrol",
		"disk": null,
		"servicecontrol": {
			"identity": "gcp",
			"serviceName": "someservice",
			"consumerId": "project:someproject"
		},
		"pubsub": null
	}],
	"sources": null,
	"filters": null
}

It looks like ubbagent is still counting feilds woth null value

make is failing with golang errors

Command to run

make clean setup deps build

Failure:

go: downloading google.golang.org/protobuf v1.27.1
go get: installing executables with 'go get' in module mode is deprecated.
	Use 'go install pkg@version' instead.
	For more information, see https://golang.org/doc/go-get-install-deprecation
	or run 'go help get' or 'go help install'.
# github.com/golang/dep/gps
.GOPATH/pkg/mod/github.com/golang/[email protected]/gps/constraint.go:103:21: cannot use sv (type *semver.Version) as type semver.Version in field value
.GOPATH/pkg/mod/github.com/golang/[email protected]/gps/constraint.go:122:16: invalid type assertion: c.(semver.Version) (non-interface type *semver.Constraints on left)
.GOPATH/pkg/mod/github.com/golang/[email protected]/gps/constraint.go:149:4: undefined: semver.Constraint
Makefile:127: recipe for target 'setup' failed
make: *** [setup] Error 2

HTTP Availability and Port

Just a comment on what I'm seeing but the default behavior of ubbagent-start is to disable HTTP access unless a port is provided. I would expect port 3456 to be used as the default (or whatever you choose).

Additionally, it's undocumented and unclear what this application should do at all if HTTP is disabled. Suggest defaulting to port 3456 and always enabling HTTP unless explicitly disabled by configuration (in the event that's useful)

Panic in ubbagent

A customer marketplace deployment hit the following issue in ubbagent:

panic: RetryingSender.maybeSend: loading from retry queue: unexpected end of JSON input
goroutine 15 [running]:
vendor/github.com/GoogleCloudPlatform/ubbagent/pipeline/senders.(*RetryingSender).maybeSend(0xc0005806e0, 0xbf97a99c50737bd1, 0x24e27478, 0x48378c0)
	/vendor/github.com/GoogleCloudPlatform/ubbagent/pipeline/senders/retry.go:199 +0x7d8
vendor/github.com/GoogleCloudPlatform/ubbagent/pipeline/senders.(*RetryingSender).run(0xc0005806e0, 0xbf97a99c50737bd1, 0x24e27478, 0x48378c0)
	/vendor/github.com/GoogleCloudPlatform/ubbagent/pipeline/senders/retry.go:149 +0x6a
created by vendor/github.com/GoogleCloudPlatform/ubbagent/pipeline/senders.newRetryingSender
	/vendor/github.com/GoogleCloudPlatform/ubbagent/pipeline/senders/retry.go:88 +0x244

message dequeue panic

I encountered an error when I send a message one but I see multiple invocations of the same message in retry.go
the message gets dequeued after the first success, when it attempts to do so in the second attempt the dequeue fails as the message is not in the queue anymore as it was dequeued in the first attempt.
This happens in case of service control endpoint and it is not an expected behaviour

To make things worse ubbagent panics resulting in the system to crash
I believe when this happens it should only log the error and move on

So we have 2 problems at hand that we must discuss:

  1. why should the dequeue panic when we can just log the error
  2. why would it try to send it twice in the first place when it already had a success sending it in the service control

Timezone parsing errors / misbehavior

{"name":"requests",
"startTime":"2018-03-26T12:39:55",
"endTime":"2018-03-26T12:39:55",
"value":{ 
  "int64Value": 10,
  "labels":{"foo":"Bar"}
 }
}

Sample input (as t.json)

Posting this:

$ curl -X post -d @t.json http://localhost:3456/report
parsing time ""2018-03-26T12:39:55"" as ""2006-01-02T15:04:05Z07:00"": cannot parse """ as "Z07:00"/ # 

Assuming timezone UTC (Z) would have made sense, but not sure where the 07:00 offset is coming from, this looks like a bug.

Go SDK

I'm trying to add Google Cloud Marketplace usage reporting to my app and following this doc it says

In the SDK approach, the agent must be compiled or linked into your app binary. The SDK is implemented natively for Go, with bindings for Python.

and I'm struggling to figure out how to use it. Am I supposed to use https://github.com/GoogleCloudPlatform/ubbagent/blob/master/sdk/sdk.go ? There's not much there...

Do you have any examples? I can't find anything. Any help you can provide is greatly appreciated it.

servicecontrol -- ???

IIUC ubbagent can forward metering metrics to an endpoint for collection.

Currently this endpoint must be configured through Google Service Control.

Google's Service Control content is dated and inaccurate:
https://cloud.google.com/service-control/overview
https://github.com/googleapis/googleapis/tree/master/google/api/servicecontrol

I assumed I could use an arbitrary service (e.g. container.googleapis.com) to get to a working ubbagent but I'm receiving 403s when I try to use these:

Permission 'servicemanagement.services.check' denied for the consumer project, forbidden

Is there a general-purpose sink that we may use for testing?
If not, am I correct in thinking that I'd need to e.g. deploy a Cloud Endpoints service to point this configuration at?

Consider ref'ing client secrets as files rather than base64 encoded data

Both Docker and Kubernetes provide simple mechanisms to convey a file (client secret) to a running container:

  • with Docker (only), this can be through a mount/volume;
  • with Kubernetes through a secret that is then mounted.

Using these mechanisms directly saves some processing steps and, I believe, aids clarity.

Would it perhaps even be possible to drop the references to the [consumer project] and robot entirely from the ubbagent config and pass these values using environment variables as is conventionally done with ADCs?

https://cloud.google.com/docs/authentication/production#auth-cloud-implicit-go

unable to configure ubb agent with my application on gke

Hi everyone

I am unable to configure my application with the usage-based billing agent. My application runs on GKE.

I have the following questions :

  1. What should be the “serviceName “ which should be given to the service control endpoint in the ubb agent config YAML . I just use the service exposed by my application .
  2. Is the usage-based billing agent a pull or a push agent?
  3. Do we need to make any changes or modifications in the application to integrate the agent . ?

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.