mirror of https://github.com/grafana/grafana
Inspector: support custom metadata display (#20854)
parent
0bf9e9bc28
commit
bf18704490
@ -0,0 +1,58 @@ |
||||
import React, { PureComponent } from 'react'; |
||||
import { MetadataInspectorProps, DataFrame } from '@grafana/data'; |
||||
import { GraphiteDatasource } from './datasource'; |
||||
import { GraphiteQuery, GraphiteOptions, MetricTankMeta, MetricTankResultMeta } from './types'; |
||||
import { parseSchemaRetentions } from './meta'; |
||||
|
||||
export type Props = MetadataInspectorProps<GraphiteDatasource, GraphiteQuery, GraphiteOptions>; |
||||
|
||||
export interface State { |
||||
index: number; |
||||
} |
||||
|
||||
export class MetricTankMetaInspector extends PureComponent<Props, State> { |
||||
state = { index: 0 }; |
||||
|
||||
renderInfo = (info: MetricTankResultMeta, frame: DataFrame) => { |
||||
const buckets = parseSchemaRetentions(info['schema-retentions']); |
||||
return ( |
||||
<div> |
||||
<h3>Info</h3> |
||||
<table> |
||||
<tbody> |
||||
{buckets.map(row => ( |
||||
<tr key={row.interval}> |
||||
<td>{row.interval} </td> |
||||
<td>{row.retention} </td> |
||||
<td>{row.chunkspan} </td> |
||||
<td>{row.numchunks} </td> |
||||
<td>{row.ready} </td> |
||||
</tr> |
||||
))} |
||||
</tbody> |
||||
</table> |
||||
<pre>{JSON.stringify(info, null, 2)}</pre> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
render() { |
||||
const { data } = this.props; |
||||
if (!data || !data.length) { |
||||
return <div>No Metadata</div>; |
||||
} |
||||
|
||||
const frame = data[this.state.index]; |
||||
const meta = frame.meta?.custom as MetricTankMeta; |
||||
if (!meta || !meta.info) { |
||||
return <>No Metadatata on DataFrame</>; |
||||
} |
||||
return ( |
||||
<div> |
||||
<h3>MetricTank Request</h3> |
||||
<pre>{JSON.stringify(meta.request, null, 2)}</pre> |
||||
{meta.info.map(info => this.renderInfo(info, frame))} |
||||
</div> |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,40 @@ |
||||
import { parseSchemaRetentions } from './meta'; |
||||
|
||||
describe('metadata parsing', () => { |
||||
it('should parse schema retentions', () => { |
||||
const retentions = '1s:35d:20min:5:1542274085,1min:38d:2h:1:true,10min:120d:6h:1:true,2h:2y:6h:2'; |
||||
const info = parseSchemaRetentions(retentions); |
||||
expect(info).toMatchInlineSnapshot(` |
||||
Array [ |
||||
Object { |
||||
"chunkspan": "20min", |
||||
"interval": "1s", |
||||
"numchunks": 5, |
||||
"ready": 1542274085, |
||||
"retention": "35d", |
||||
}, |
||||
Object { |
||||
"chunkspan": "2h", |
||||
"interval": "1min", |
||||
"numchunks": 1, |
||||
"ready": true, |
||||
"retention": "38d", |
||||
}, |
||||
Object { |
||||
"chunkspan": "6h", |
||||
"interval": "10min", |
||||
"numchunks": 1, |
||||
"ready": true, |
||||
"retention": "120d", |
||||
}, |
||||
Object { |
||||
"chunkspan": "6h", |
||||
"interval": "2h", |
||||
"numchunks": 2, |
||||
"ready": undefined, |
||||
"retention": "2y", |
||||
}, |
||||
] |
||||
`);
|
||||
}); |
||||
}); |
@ -0,0 +1,49 @@ |
||||
export interface MetricTankResultMeta { |
||||
'schema-name': string; |
||||
'schema-retentions': string; //"1s:35d:20min:5:1542274085,1min:38d:2h:1:true,10min:120d:6h:1:true,2h:2y:6h:2",
|
||||
} |
||||
|
||||
// https://github.com/grafana/metrictank/blob/master/scripts/config/storage-schemas.conf#L15-L46
|
||||
|
||||
export interface RetentionInfo { |
||||
interval: string; |
||||
retention?: string; |
||||
chunkspan?: string; |
||||
numchunks?: number; |
||||
ready?: boolean | number; // whether, or as of what data timestamp, the archive is ready for querying.
|
||||
} |
||||
|
||||
function toInteger(val?: string): number | undefined { |
||||
if (val) { |
||||
return parseInt(val, 10); |
||||
} |
||||
return undefined; |
||||
} |
||||
function toBooleanOrTimestamp(val?: string): number | boolean | undefined { |
||||
if (val) { |
||||
if (val === 'true') { |
||||
return true; |
||||
} |
||||
if (val === 'false') { |
||||
return false; |
||||
} |
||||
return parseInt(val, 10); |
||||
} |
||||
return undefined; |
||||
} |
||||
|
||||
export function parseSchemaRetentions(spec: string): RetentionInfo[] { |
||||
if (!spec) { |
||||
return []; |
||||
} |
||||
return spec.split(',').map(str => { |
||||
const vals = str.split(':'); |
||||
return { |
||||
interval: vals[0], |
||||
retention: vals[1], |
||||
chunkspan: vals[2], |
||||
numchunks: toInteger(vals[3]), |
||||
ready: toBooleanOrTimestamp(vals[4]), |
||||
}; |
||||
}); |
||||
} |
Loading…
Reference in new issue