Jump to: navigation, search

Difference between revisions of "Obsolete:Ceilometer/blueprints/APIv2"

 
(10 intermediate revisions by 3 users not shown)
Line 1: Line 1:
__NOTOC__
+
 
 
* '''Launchpad Entry''': [[CeilometerSpec]]:API v2
 
* '''Launchpad Entry''': [[CeilometerSpec]]:API v2
 
* '''Created''': 6 December 2012
 
* '''Created''': 6 December 2012
Line 19: Line 19:
 
</nowiki></pre>
 
</nowiki></pre>
  
 +
 +
Note I started with this:
 +
https://github.com/asalkeld/ceilometer/commit/c678ff8abd2a91c4404657748b9ed9b31c1541df
  
 
== Release Note ==
 
== Release Note ==
Line 27: Line 30:
  
 
* '''Meter''' == definition of the measurement (name,ownership,resource,metadata) - synonyms (metric)
 
* '''Meter''' == definition of the measurement (name,ownership,resource,metadata) - synonyms (metric)
* '''Sample''' == the actual data values (value,unit,timestamp) synonyms (measurement)
+
* '''Sample''' == the actual data values (value,unit,timestamp) synonyms (measurement) (replaces "Event")
 
* '''Resource''' is an openstack object created for a user (eg. instance, volume)  
 
* '''Resource''' is an openstack object created for a user (eg. instance, volume)  
 
* '''User''' is an openstack user auth'ed by keystone
 
* '''User''' is an openstack user auth'ed by keystone
* '''Source''' is the origin of a sample (usually "openstack" but could be a url).
+
* '''Source''' is the origin for the User and Project/Tenant (usually "openstack").
 
* '''Gauge''' is a type of Meter absolute measurement (car: revs per minute)
 
* '''Gauge''' is a type of Meter absolute measurement (car: revs per minute)
 
* '''Counter''' is a type of Meter that counts upwards (car: distance travelled - assume you don't reverse a lot:-)
 
* '''Counter''' is a type of Meter that counts upwards (car: distance travelled - assume you don't reverse a lot:-)
Line 40: Line 43:
 
* Resources are implicitly created by creating new Meters
 
* Resources are implicitly created by creating new Meters
 
* Passing arrays needs to be done like this ''class[index].property=value''
 
* Passing arrays needs to be done like this ''class[index].property=value''
 +
* The relationship between objects does not change (resource -> meter -> sample)
 +
  So the same db schema (at least in mongo)
  
 
== Design ==
 
== Design ==
Line 58: Line 63:
 
| GET
 
| GET
 
| /meters/<meter>
 
| /meters/<meter>
 +
|-
 +
| GET
 +
| /meters/<meter>/statistics
 
|-
 
|-
 
| POST
 
| POST
Line 84: Line 92:
  
 
<pre><nowiki>
 
<pre><nowiki>
s[].name=field
+
s[]=field
 
</nowiki></pre>
 
</nowiki></pre>
  
Line 94: Line 102:
 
* listing with the common Query mechanism
 
* listing with the common Query mechanism
 
* get a single resource
 
* get a single resource
 +
 +
So just a resource_id makes the resource unique.
  
 
=== Meter Resources ===
 
=== Meter Resources ===
  
Computation (acts on value/volume and assumes a period)
+
'''GET /v2/meters'''
c[].name={sum|max|min|ave|len}
+
 
 +
Returns a list of available meters that match the Query (if given).
 +
 
 +
'''POST /v2/meters'''
 +
 
 +
The body:
 +
 
 +
'''GET /v2/meters/<meter>'''
 +
 
 +
Get the meter samples match the Query (if given) and return the raw samples.
 +
 
 +
'''GET /v2/meters/<meter>/statistics'''
 +
Get the derived statistics
 +
 
 +
 
 +
<pre><nowiki>
 +
{
 +
'min': 3,
 +
'max': 20,
 +
'avg': 8,
 +
'sum': 45,
 +
'duration': <actual difference between the first and last sample that the stats were calulated from>
 +
}
 +
</nowiki></pre>
 +
 
  
 +
The period is to define the time period over which to calculate the above values.
 +
 +
<pre><nowiki>
 
Period
 
Period
 +
</nowiki></pre>
 +
 +
 +
Example:
 +
 +
<pre><nowiki>
 +
/v2/meters/cpu_util/statistics?
 +
q[0].field=metadata.autoscale_group&
 +
q[0].op=eq&
 +
q[0].value=all_mine&
 +
q[1].field=timestamp&
 +
q[1].op=lt&
 +
q[1].value=<now>&
 +
q[2].field=timestamp&
 +
q[2].op=gt&
 +
q[2].value=<now - 5 hours>&
 +
period=360
 +
</nowiki></pre>
 +
 +
The above gets all the ''cpu_util'' samples with metadata.autoscale_group=all_mine
 +
between 5hours ago and now. Then calulates the min, max and avg for each hour.
 +
This would return something like this:
 +
 +
<pre><nowiki>
 +
{[
 +
{min=12, max=34, avg=23},
 +
{min=14, max=41, avg=26},
 +
{min=15, max=43, avg=29},
 +
{min=16, max=44, avg=34},
 +
{min=18, max=47, avg=33},
 +
]}
 +
</nowiki></pre>
 +
  
 
== Implementation ==
 
== Implementation ==
Line 113: Line 183:
  
 
== Unresolved issues ==
 
== Unresolved issues ==
Do we need to keep the following queries:
+
'''QU: Do we need to keep the following queries:'''
  
 
<pre><nowiki>
 
<pre><nowiki>
Line 122: Line 192:
  
 
Basically are these queries been used at the moment?
 
Basically are these queries been used at the moment?
 +
 +
ANS: The DUDE lists resources in a project and then asks questions about the meters reporting data for the resource. We do not use these queries. - dhellmann
 +
 +
'''QU: The API includes passing a period over which Calculations are done'''
 +
 +
This produces output like:
 +
 +
<pre><nowiki>
 +
{[
 +
{min=12, max=34, avg=23},
 +
{min=14, max=41, avg=26},
 +
...
 +
</nowiki></pre>
 +
 +
Is this neat/super useful or unnecessary?
 +
 +
Do you have ideas for how to implement this? I think I can envision how to do it in a clumsy way with mapreduce, but I don't know about the SQL. - dhellmann
 +
 +
Well we could split up the periods in the api, then the db could return all statistical calculations for that one period.
 +
 +
So the db api could look like:
 +
 +
<pre><nowiki>
 +
def get_samples(meter, query):
 +
    '''just return the raw samples that match the query'''
 +
def get_statistics(meter, query):
 +
    '''return (max,min,avg,len,duration) for the given query'''
 +
</nowiki></pre>
 +
  
 
== BoF agenda and discussion ==
 
== BoF agenda and discussion ==

Latest revision as of 19:07, 11 May 2016

  • Launchpad Entry: CeilometerSpec:API v2
  • Created: 6 December 2012
  • Contributors: Angus Salkeld

Summary

Our current API is very nested and looks great as a link, but makes it a bit painful to add new features as they need to be added in so many places. Also the test case blow out too. So lets use optional arguments for filters instead of resource ownership.


So:
 /resources?source=elsewhere
rather than
 /sources/elsewhere/resources


Note I started with this: https://github.com/asalkeld/ceilometer/commit/c678ff8abd2a91c4404657748b9ed9b31c1541df

Release Note

Rationale

Terminology

  • Meter == definition of the measurement (name,ownership,resource,metadata) - synonyms (metric)
  • Sample == the actual data values (value,unit,timestamp) synonyms (measurement) (replaces "Event")
  • Resource is an openstack object created for a user (eg. instance, volume)
  • User is an openstack user auth'ed by keystone
  • Source is the origin for the User and Project/Tenant (usually "openstack").
  • Gauge is a type of Meter absolute measurement (car: revs per minute)
  • Counter is a type of Meter that counts upwards (car: distance travelled - assume you don't reverse a lot:-)

User stories

Assumptions

  • Resources are implicitly created by creating new Meters
  • Passing arrays needs to be done like this class[index].property=value
  • The relationship between objects does not change (resource -> meter -> sample)
  So the same db schema (at least in mongo)

Design

Query Type Resource
GET /resources
GET /resources/<resource_id>
GET /meters
GET /meters/<meter>
GET /meters/<meter>/statistics
POST /meters
PUT /meters/<meter>
DELETE /meters/<meter>

Generic optional arguments

Query:

q[].field=name
q[].op=eq
q[].value=56

op is the comparison operation (eq, gt, lt, etc)

Field Selection

s[]=field

This is a way to choose the field that get returned. If you leave this out we default to returning all field.

Resource Resources

Same as currently, but we support the following actions

  • listing with the common Query mechanism
  • get a single resource

So just a resource_id makes the resource unique.

Meter Resources

GET /v2/meters

Returns a list of available meters that match the Query (if given).

POST /v2/meters

The body:

GET /v2/meters/<meter>

Get the meter samples match the Query (if given) and return the raw samples.

GET /v2/meters/<meter>/statistics Get the derived statistics


{
'min': 3,
'max': 20,
'avg': 8,
'sum': 45,
'duration': <actual difference between the first and last sample that the stats were calulated from>
}


The period is to define the time period over which to calculate the above values.

Period


Example:

/v2/meters/cpu_util/statistics?
 q[0].field=metadata.autoscale_group&
 q[0].op=eq&
 q[0].value=all_mine&
 q[1].field=timestamp&
 q[1].op=lt&
 q[1].value=<now>&
 q[2].field=timestamp&
 q[2].op=gt&
 q[2].value=<now - 5 hours>&
 period=360

The above gets all the cpu_util samples with metadata.autoscale_group=all_mine between 5hours ago and now. Then calulates the min, max and avg for each hour. This would return something like this:

{[
{min=12, max=34, avg=23},
{min=14, max=41, avg=26},
{min=15, max=43, avg=29},
{min=16, max=44, avg=34},
{min=18, max=47, avg=33},
]}


Implementation

UI Changes

Code Changes

Migration

Test/Demo Plan

Unresolved issues

QU: Do we need to keep the following queries:

 /sources
 /projects
 /users

Basically are these queries been used at the moment?

ANS: The DUDE lists resources in a project and then asks questions about the meters reporting data for the resource. We do not use these queries. - dhellmann

QU: The API includes passing a period over which Calculations are done

This produces output like:

{[
{min=12, max=34, avg=23},
{min=14, max=41, avg=26},
...

Is this neat/super useful or unnecessary?

Do you have ideas for how to implement this? I think I can envision how to do it in a clumsy way with mapreduce, but I don't know about the SQL. - dhellmann

Well we could split up the periods in the api, then the db could return all statistical calculations for that one period.

So the db api could look like:

def get_samples(meter, query):
    '''just return the raw samples that match the query'''
def get_statistics(meter, query):
    '''return (max,min,avg,len,duration) for the given query'''


BoF agenda and discussion

Use this section to take notes during the BoF; if you keep it in the approved spec, use it for summarising what was discussed and note any options that were rejected.