Rename telemetry_metadata table to just metadata

This change renames the _timescale_catalog.telemetry_metadata to
_timescale_catalog.metadata.  It also adds a new boolean column to this
table which is used to flag data which should be included in telemetry.

It also renamed the src/telemetry/metadata.{h,c} files to
src/telemetry/telemetry_metadata.{h,c} and updated the API to reflect
this.  Finally it also includes the logic to use the new boolean column
when populating the telemetry parse state.
This commit is contained in:
Brian Rowe 2019-05-02 08:25:25 -07:00
parent f0f1b47df9
commit aeac52aef6
25 changed files with 245 additions and 235 deletions

View File

@ -35,7 +35,7 @@ set(SOURCE_FILES
histogram.sql histogram.sql
cache.sql cache.sql
bgw_scheduler.sql bgw_scheduler.sql
telemetry_metadata.sql metadata.sql
views.sql views.sql
gapfill.sql gapfill.sql
maintenance_utils.sql maintenance_utils.sql

View File

@ -8,7 +8,7 @@ AS '@MODULE_PATHNAME@', 'ts_uuid_generate' LANGUAGE C VOLATILE STRICT;
-- Insert uuid and install_timestamp on database creation. Don't -- Insert uuid and install_timestamp on database creation. Don't
-- create exported_uuid because it gets exported and installed during -- create exported_uuid because it gets exported and installed during
-- pg_dump, which would cause a conflict. -- pg_dump, which would cause a conflict.
INSERT INTO _timescaledb_catalog.telemetry_metadata INSERT INTO _timescaledb_catalog.metadata
SELECT 'uuid', _timescaledb_internal.generate_uuid() ON CONFLICT DO NOTHING; SELECT 'uuid', _timescaledb_internal.generate_uuid(), TRUE ON CONFLICT DO NOTHING;
INSERT INTO _timescaledb_catalog.telemetry_metadata INSERT INTO _timescaledb_catalog.metadata
SELECT 'install_timestamp', now() ON CONFLICT DO NOTHING; SELECT 'install_timestamp', now(), TRUE ON CONFLICT DO NOTHING;

View File

@ -215,11 +215,12 @@ CREATE TABLE IF NOT EXISTS _timescaledb_internal.bgw_policy_chunk_stats (
UNIQUE(job_id,chunk_id) UNIQUE(job_id,chunk_id)
); );
CREATE TABLE IF NOT EXISTS _timescaledb_catalog.telemetry_metadata ( CREATE TABLE IF NOT EXISTS _timescaledb_catalog.metadata (
key NAME NOT NULL PRIMARY KEY, key NAME NOT NULL PRIMARY KEY,
value TEXT NOT NULL value TEXT NOT NULL,
include_in_telemetry BOOLEAN NOT NULL
); );
SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.telemetry_metadata', $$WHERE key='exported_uuid'$$); SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.metadata', $$WHERE key='exported_uuid'$$);
CREATE TABLE IF NOT EXISTS _timescaledb_catalog.continuous_agg ( CREATE TABLE IF NOT EXISTS _timescaledb_catalog.continuous_agg (
mat_hypertable_id INTEGER PRIMARY KEY REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE, mat_hypertable_id INTEGER PRIMARY KEY REFERENCES _timescaledb_catalog.hypertable(id) ON DELETE CASCADE,

View File

@ -0,0 +1,4 @@
ALTER TABLE _timescaledb_catalog.telemetry_metadata ADD COLUMN include_in_telemetry BOOLEAN NOT NULL DEFAULT TRUE;
ALTER TABLE _timescaledb_catalog.telemetry_metadata ALTER COLUMN include_in_telemetry DROP DEFAULT;
ALTER TABLE _timescaledb_catalog.telemetry_metadata RENAME TO metadata;
ALTER INDEX _timescaledb_catalog.telemetry_metadata_pkey RENAME TO metadata_pkey;

View File

@ -31,7 +31,7 @@ set(SOURCES
hypertable_restrict_info.c hypertable_restrict_info.c
indexing.c indexing.c
init.c init.c
telemetry_metadata.c metadata.c
jsonb_utils.c jsonb_utils.c
license_guc.c license_guc.c
partitioning.c partitioning.c

View File

@ -62,9 +62,9 @@ static const TableInfoDef catalog_table_names[_MAX_CATALOG_TABLES + 1] = {
.schema_name = INTERNAL_SCHEMA_NAME, .schema_name = INTERNAL_SCHEMA_NAME,
.table_name = BGW_JOB_STAT_TABLE_NAME, .table_name = BGW_JOB_STAT_TABLE_NAME,
}, },
[TELEMETRY_METADATA] = { [METADATA] = {
.schema_name = CATALOG_SCHEMA_NAME, .schema_name = CATALOG_SCHEMA_NAME,
.table_name = TELEMETRY_METADATA_TABLE_NAME, .table_name = METADATA_TABLE_NAME,
}, },
[BGW_POLICY_REORDER] = { [BGW_POLICY_REORDER] = {
.schema_name = CONFIG_SCHEMA_NAME, .schema_name = CONFIG_SCHEMA_NAME,
@ -163,10 +163,10 @@ static const TableIndexDef catalog_table_index_definitions[_MAX_CATALOG_TABLES]
[BGW_JOB_STAT_PKEY_IDX] = "bgw_job_stat_pkey", [BGW_JOB_STAT_PKEY_IDX] = "bgw_job_stat_pkey",
}, },
}, },
[TELEMETRY_METADATA] = { [METADATA] = {
.length = _MAX_TELEMETRY_METADATA_INDEX, .length = _MAX_METADATA_INDEX,
.names = (char *[]) { .names = (char *[]) {
[TELEMETRY_METADATA_PKEY_IDX] = "telemetry_metadata_pkey", [METADATA_PKEY_IDX] = "metadata_pkey",
}, },
}, },
[BGW_POLICY_REORDER] = { [BGW_POLICY_REORDER] = {

View File

@ -43,7 +43,7 @@ typedef enum CatalogTable
TABLESPACE, TABLESPACE,
BGW_JOB, BGW_JOB,
BGW_JOB_STAT, BGW_JOB_STAT,
TELEMETRY_METADATA, METADATA,
BGW_POLICY_REORDER, BGW_POLICY_REORDER,
BGW_POLICY_DROP_CHUNKS, BGW_POLICY_DROP_CHUNKS,
BGW_POLICY_CHUNK_STATS, BGW_POLICY_CHUNK_STATS,
@ -594,42 +594,43 @@ enum Anum_bgw_job_stat_pkey_idx
/****************************** /******************************
* *
* telemetry_metadata table definitions * metadata table definitions
* *
******************************/ ******************************/
#define TELEMETRY_METADATA_TABLE_NAME "telemetry_metadata" #define METADATA_TABLE_NAME "metadata"
enum Anum_telemetry_metadata enum Anum_metadata
{ {
Anum_telemetry_metadata_key = 1, Anum_metadata_key = 1,
Anum_telemetry_metadata_value, Anum_metadata_value,
_Anum_telemetry_metadata_max, Anum_metadata_include_in_telemetry,
_Anum_metadata_max,
}; };
#define Natts_telemetry_metadata (_Anum_telemetry_metadata_max - 1) #define Natts_metadata (_Anum_metadata_max - 1)
typedef struct FormData_telemetry_metadata typedef struct FormData_metadata
{ {
NameData key; NameData key;
text *value; text *value;
} FormData_telemetry_metadata; } FormData_metadata;
typedef FormData_telemetry_metadata *Form_telemetry_metadata; typedef FormData_metadata *Form_metadata;
/* telemetry_metadata primary index attribute numbers */ /* metadata primary index attribute numbers */
enum Anum_telemetry_metadata_pkey_idx enum Anum_metadata_pkey_idx
{ {
Anum_telemetry_metadata_pkey_idx_id = 1, Anum_metadata_pkey_idx_id = 1,
_Anum_telemetry_metadata_pkey_max, _Anum_metadata_pkey_max,
}; };
#define Natts_telemetry_metadata_pkey_idx (_Anum_telemetry_metadata_pkey_max - 1) #define Natts_metadata_pkey_idx (_Anum_metadata_pkey_max - 1)
enum enum
{ {
TELEMETRY_METADATA_PKEY_IDX = 0, METADATA_PKEY_IDX = 0,
_MAX_TELEMETRY_METADATA_INDEX, _MAX_METADATA_INDEX,
}; };
/****** BGW_POLICY_REORDER TABLE definitions */ /****** BGW_POLICY_REORDER TABLE definitions */

View File

@ -15,11 +15,11 @@
#include <utils/datum.h> #include <utils/datum.h>
#include "catalog.h" #include "catalog.h"
#include "telemetry_metadata.h" #include "metadata.h"
#include "scanner.h" #include "scanner.h"
#define TYPE_ERROR(inout, typeid) \ #define TYPE_ERROR(inout, typeid) \
elog(ERROR, "ts::telemetry_metadata: no %s function for type %u", inout, typeid); elog(ERROR, "ts_metadata: no %s function for type %u", inout, typeid);
static Datum static Datum
convert_type(PGFunction func, Datum value, Oid from_type) convert_type(PGFunction func, Datum value, Oid from_type)
@ -64,18 +64,18 @@ typedef struct DatumValue
* that pgindent works. It can be removed from this struct in case we * that pgindent works. It can be removed from this struct in case we
* actually use the form type in code * actually use the form type in code
*/ */
FormData_telemetry_metadata *form; FormData_metadata *form;
Datum value; Datum value;
Oid typeid; Oid typeid;
bool isnull; bool isnull;
} DatumValue; } DatumValue;
static ScanTupleResult static ScanTupleResult
telemetry_metadata_tuple_get_value(TupleInfo *ti, void *data) metadata_tuple_get_value(TupleInfo *ti, void *data)
{ {
DatumValue *dv = data; DatumValue *dv = data;
dv->value = heap_getattr(ti->tuple, Anum_telemetry_metadata_value, ti->desc, &dv->isnull); dv->value = heap_getattr(ti->tuple, Anum_metadata_value, ti->desc, &dv->isnull);
if (!dv->isnull) if (!dv->isnull)
dv->value = convert_text_to_type(dv->value, dv->typeid); dv->value = convert_text_to_type(dv->value, dv->typeid);
@ -84,8 +84,8 @@ telemetry_metadata_tuple_get_value(TupleInfo *ti, void *data)
} }
static Datum static Datum
telemetry_metadata_get_value_internal(Datum metadata_key, Oid key_type, Oid value_type, metadata_get_value_internal(Datum metadata_key, Oid key_type, Oid value_type, bool *isnull,
bool *isnull, LOCKMODE lockmode) LOCKMODE lockmode)
{ {
ScanKeyData scankey[1]; ScanKeyData scankey[1];
DatumValue dv = { DatumValue dv = {
@ -94,18 +94,18 @@ telemetry_metadata_get_value_internal(Datum metadata_key, Oid key_type, Oid valu
}; };
Catalog *catalog = ts_catalog_get(); Catalog *catalog = ts_catalog_get();
ScannerCtx scanctx = { ScannerCtx scanctx = {
.table = catalog_get_table_id(catalog, TELEMETRY_METADATA), .table = catalog_get_table_id(catalog, METADATA),
.index = catalog_get_index(catalog, TELEMETRY_METADATA, TELEMETRY_METADATA_PKEY_IDX), .index = catalog_get_index(catalog, METADATA, METADATA_PKEY_IDX),
.nkeys = 1, .nkeys = 1,
.scankey = scankey, .scankey = scankey,
.tuple_found = telemetry_metadata_tuple_get_value, .tuple_found = metadata_tuple_get_value,
.data = &dv, .data = &dv,
.lockmode = lockmode, .lockmode = lockmode,
.scandirection = ForwardScanDirection, .scandirection = ForwardScanDirection,
}; };
ScanKeyInit(&scankey[0], ScanKeyInit(&scankey[0],
Anum_telemetry_metadata_key, Anum_metadata_key,
BTEqualStrategyNumber, BTEqualStrategyNumber,
F_NAMEEQ, F_NAMEEQ,
convert_type_to_name(metadata_key, key_type)); convert_type_to_name(metadata_key, key_type));
@ -119,17 +119,13 @@ telemetry_metadata_get_value_internal(Datum metadata_key, Oid key_type, Oid valu
} }
Datum Datum
ts_telemetry_metadata_get_value(Datum metadata_key, Oid key_type, Oid value_type, bool *isnull) ts_metadata_get_value(Datum metadata_key, Oid key_type, Oid value_type, bool *isnull)
{ {
return telemetry_metadata_get_value_internal(metadata_key, return metadata_get_value_internal(metadata_key, key_type, value_type, isnull, AccessShareLock);
key_type,
value_type,
isnull,
AccessShareLock);
} }
/* /*
* Insert a row into the telemetry_metadata table. Acquires a lock in * Insert a row into the metadata table. Acquires a lock in
* SHARE ROW EXCLUSIVE mode to conflict with itself, and then verifies that * SHARE ROW EXCLUSIVE mode to conflict with itself, and then verifies that
* the desired metadata KV pair still does not exist. Otherwise, exits * the desired metadata KV pair still does not exist. Otherwise, exits
* without inserting to avoid underlying database error on PK conflict. * without inserting to avoid underlying database error on PK conflict.
@ -137,23 +133,24 @@ ts_telemetry_metadata_get_value(Datum metadata_key, Oid key_type, Oid value_type
* the existing value if nothing was inserted. * the existing value if nothing was inserted.
*/ */
Datum Datum
ts_telemetry_metadata_insert(Datum metadata_key, Oid key_type, Datum metadata_value, Oid value_type) ts_metadata_insert(Datum metadata_key, Oid key_type, Datum metadata_value, Oid value_type,
bool include_in_telemetry)
{ {
Datum existing_value; Datum existing_value;
Datum values[Natts_telemetry_metadata]; Datum values[Natts_metadata];
bool nulls[Natts_telemetry_metadata] = { false }; bool nulls[Natts_metadata] = { false };
bool isnull = false; bool isnull = false;
Catalog *catalog = ts_catalog_get(); Catalog *catalog = ts_catalog_get();
Relation rel; Relation rel;
rel = heap_open(catalog_get_table_id(catalog, TELEMETRY_METADATA), ShareRowExclusiveLock); rel = heap_open(catalog_get_table_id(catalog, METADATA), ShareRowExclusiveLock);
/* Check for row existence while we have the lock */ /* Check for row existence while we have the lock */
existing_value = telemetry_metadata_get_value_internal(metadata_key, existing_value = metadata_get_value_internal(metadata_key,
key_type, key_type,
value_type, value_type,
&isnull, &isnull,
ShareRowExclusiveLock); ShareRowExclusiveLock);
if (!isnull) if (!isnull)
{ {
@ -162,10 +159,12 @@ ts_telemetry_metadata_insert(Datum metadata_key, Oid key_type, Datum metadata_va
} }
/* Insert into the catalog table for persistence */ /* Insert into the catalog table for persistence */
values[AttrNumberGetAttrOffset(Anum_telemetry_metadata_key)] = values[AttrNumberGetAttrOffset(Anum_metadata_key)] =
convert_type_to_name(metadata_key, key_type); convert_type_to_name(metadata_key, key_type);
values[AttrNumberGetAttrOffset(Anum_telemetry_metadata_value)] = values[AttrNumberGetAttrOffset(Anum_metadata_value)] =
convert_type_to_text(metadata_value, value_type); convert_type_to_text(metadata_value, value_type);
values[AttrNumberGetAttrOffset(Anum_metadata_include_in_telemetry)] =
BoolGetDatum(include_in_telemetry);
ts_catalog_insert_values(rel, RelationGetDescr(rel), values, nulls); ts_catalog_insert_values(rel, RelationGetDescr(rel), values, nulls);

15
src/metadata.h Normal file
View File

@ -0,0 +1,15 @@
/*
* This file and its contents are licensed under the Apache License 2.0.
* Please see the included NOTICE for copyright information and
* LICENSE-APACHE for a copy of the license.
*/
#ifndef TIMESCALEDB_METADATA_H
#define TIMESCALEDB_METADATA_H
#include <postgres.h>
extern Datum ts_metadata_get_value(Datum metadata_key, Oid key_type, Oid value_type, bool *isnull);
extern Datum ts_metadata_insert(Datum metadata_key, Oid key_type, Datum metadata_value,
Oid value_type, bool include_in_telemetry);
#endif /* TIMESCALEDB_METADATA_H */

View File

@ -1,7 +1,7 @@
# Add all *.c to sources in upperlevel directory # Add all *.c to sources in upperlevel directory
set(SOURCES set(SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/uuid.c ${CMAKE_CURRENT_SOURCE_DIR}/uuid.c
${CMAKE_CURRENT_SOURCE_DIR}/metadata.c ${CMAKE_CURRENT_SOURCE_DIR}/telemetry_metadata.c
${CMAKE_CURRENT_SOURCE_DIR}/telemetry.c ${CMAKE_CURRENT_SOURCE_DIR}/telemetry.c
) )
target_sources(${PROJECT_NAME} PRIVATE ${SOURCES}) target_sources(${PROJECT_NAME} PRIVATE ${SOURCES})

View File

@ -1,108 +0,0 @@
/*
* This file and its contents are licensed under the Apache License 2.0.
* Please see the included NOTICE for copyright information and
* LICENSE-APACHE for a copy of the license.
*/
#include <postgres.h>
#include <catalog/pg_type.h>
#include <utils/builtins.h>
#include <utils/timestamp.h>
#include "catalog.h"
#include "telemetry_metadata.h"
#include "telemetry/uuid.h"
#include "telemetry/metadata.h"
#include "scan_iterator.h"
#include "jsonb_utils.h"
#define TELEMETRY_METADATA_UUID_KEY_NAME "uuid"
#define TELEMETRY_METADATA_EXPORTED_UUID_KEY_NAME "exported_uuid"
#define TELEMETRY_METADATA_TIMESTAMP_KEY_NAME "install_timestamp"
/*
* add all entries from _timescaledb_catalog.telemetry_metadata
*/
void
ts_metadata_add_values(JsonbParseState *state)
{
Datum key, value;
bool key_isnull, value_isnull;
ScanIterator iterator =
ts_scan_iterator_create(TELEMETRY_METADATA, AccessShareLock, CurrentMemoryContext);
iterator.ctx.index =
catalog_get_index(ts_catalog_get(), TELEMETRY_METADATA, TELEMETRY_METADATA_PKEY_IDX);
ts_scanner_foreach(&iterator)
{
TupleInfo *ti = iterator.tinfo;
key = heap_getattr(ti->tuple, Anum_telemetry_metadata_key, ti->desc, &key_isnull);
if (!key_isnull)
{
Name key_name = DatumGetName(key);
/* skip keys included as toplevel items */
if (namestrcmp(key_name, TELEMETRY_METADATA_UUID_KEY_NAME) != 0 &&
namestrcmp(key_name, TELEMETRY_METADATA_EXPORTED_UUID_KEY_NAME) != 0 &&
namestrcmp(key_name, TELEMETRY_METADATA_TIMESTAMP_KEY_NAME) != 0)
{
value =
heap_getattr(ti->tuple, Anum_telemetry_metadata_value, ti->desc, &value_isnull);
if (!value_isnull)
ts_jsonb_add_str(state, DatumGetCString(key), TextDatumGetCString(value));
}
}
}
}
static Datum
get_uuid_by_key(const char *key)
{
bool isnull;
Datum uuid;
uuid = ts_telemetry_metadata_get_value(CStringGetDatum(key), CSTRINGOID, UUIDOID, &isnull);
if (isnull)
uuid = ts_telemetry_metadata_insert(CStringGetDatum(key),
CSTRINGOID,
UUIDPGetDatum(ts_uuid_create()),
UUIDOID);
return uuid;
}
Datum
ts_metadata_get_uuid(void)
{
return get_uuid_by_key(TELEMETRY_METADATA_UUID_KEY_NAME);
}
Datum
ts_metadata_get_exported_uuid(void)
{
return get_uuid_by_key(TELEMETRY_METADATA_EXPORTED_UUID_KEY_NAME);
}
Datum
ts_metadata_get_install_timestamp(void)
{
bool isnull;
Datum timestamp;
timestamp =
ts_telemetry_metadata_get_value(CStringGetDatum(TELEMETRY_METADATA_TIMESTAMP_KEY_NAME),
CSTRINGOID,
TIMESTAMPTZOID,
&isnull);
if (isnull)
timestamp =
ts_telemetry_metadata_insert(CStringGetDatum(TELEMETRY_METADATA_TIMESTAMP_KEY_NAME),
CSTRINGOID,
TimestampTzGetDatum(GetCurrentTimestamp()),
TIMESTAMPTZOID);
return timestamp;
}

View File

@ -1,17 +0,0 @@
/*
* This file and its contents are licensed under the Apache License 2.0.
* Please see the included NOTICE for copyright information and
* LICENSE-APACHE for a copy of the license.
*/
#ifndef TIMESCALEDB_TELEMETRY__METADATA_H
#define TIMESCALEDB_TELEMETRY__METADATA_H
#include <postgres.h>
#include <utils/jsonb.h>
extern void ts_metadata_add_values(JsonbParseState *state);
extern Datum ts_metadata_get_uuid(void);
extern Datum ts_metadata_get_exported_uuid(void);
extern Datum ts_metadata_get_install_timestamp(void);
#endif /* TIMESCALEDB_TELEMETRY__METADATA_H */

View File

@ -17,7 +17,7 @@
#include "version.h" #include "version.h"
#include "guc.h" #include "guc.h"
#include "telemetry.h" #include "telemetry.h"
#include "metadata.h" #include "telemetry_metadata.h"
#include "hypertable.h" #include "hypertable.h"
#include "extension.h" #include "extension.h"
#include "net/http.h" #include "net/http.h"
@ -53,7 +53,7 @@
#define REQ_NUM_REORDER_POLICIES "num_reorder_policies" #define REQ_NUM_REORDER_POLICIES "num_reorder_policies"
#define REQ_NUM_DROP_CHUNKS_POLICIES "num_drop_chunks_policies" #define REQ_NUM_DROP_CHUNKS_POLICIES "num_drop_chunks_policies"
#define REQ_RELATED_EXTENSIONS "related_extensions" #define REQ_RELATED_EXTENSIONS "related_extensions"
#define REQ_TELEMETRY_METADATA "db_metadata" #define REQ_METADATA "db_metadata"
#define REQ_LICENSE_INFO "license" #define REQ_LICENSE_INFO "license"
#define REQ_LICENSE_EDITION "edition" #define REQ_LICENSE_EDITION "edition"
#define REQ_LICENSE_EDITION_APACHE "apache_only" #define REQ_LICENSE_EDITION_APACHE "apache_only"
@ -251,15 +251,17 @@ build_version_body(void)
ts_jsonb_add_str(parseState, ts_jsonb_add_str(parseState,
REQ_DB_UUID, REQ_DB_UUID,
DatumGetCString(DirectFunctionCall1(uuid_out, ts_metadata_get_uuid()))); DatumGetCString(
DirectFunctionCall1(uuid_out, ts_telemetry_metadata_get_uuid())));
ts_jsonb_add_str(parseState, ts_jsonb_add_str(parseState,
REQ_EXPORTED_DB_UUID, REQ_EXPORTED_DB_UUID,
DatumGetCString( DatumGetCString(
DirectFunctionCall1(uuid_out, ts_metadata_get_exported_uuid()))); DirectFunctionCall1(uuid_out, ts_telemetry_metadata_get_exported_uuid())));
ts_jsonb_add_str(parseState, ts_jsonb_add_str(parseState,
REQ_INSTALL_TIME, REQ_INSTALL_TIME,
DatumGetCString(DirectFunctionCall1(timestamptz_out, DatumGetCString(
ts_metadata_get_install_timestamp()))); DirectFunctionCall1(timestamptz_out,
ts_telemetry_metadata_get_install_timestamp())));
ts_jsonb_add_str(parseState, REQ_INSTALL_METHOD, TIMESCALEDB_INSTALL_METHOD); ts_jsonb_add_str(parseState, REQ_INSTALL_METHOD, TIMESCALEDB_INSTALL_METHOD);
@ -322,13 +324,13 @@ build_version_body(void)
pushJsonbValue(&parseState, WJB_END_OBJECT, NULL); pushJsonbValue(&parseState, WJB_END_OBJECT, NULL);
} }
/* Add additional content from telemetry_metadata */ /* Add additional content from metadata */
ext_key.type = jbvString; ext_key.type = jbvString;
ext_key.val.string.val = REQ_TELEMETRY_METADATA; ext_key.val.string.val = REQ_METADATA;
ext_key.val.string.len = strlen(REQ_TELEMETRY_METADATA); ext_key.val.string.len = strlen(REQ_METADATA);
pushJsonbValue(&parseState, WJB_KEY, &ext_key); pushJsonbValue(&parseState, WJB_KEY, &ext_key);
pushJsonbValue(&parseState, WJB_BEGIN_OBJECT, NULL); pushJsonbValue(&parseState, WJB_BEGIN_OBJECT, NULL);
ts_metadata_add_values(parseState); ts_telemetry_metadata_add_values(parseState);
pushJsonbValue(&parseState, WJB_END_OBJECT, NULL); pushJsonbValue(&parseState, WJB_END_OBJECT, NULL);
/* end of telemetry object */ /* end of telemetry object */

View File

@ -0,0 +1,110 @@
/*
* This file and its contents are licensed under the Apache License 2.0.
* Please see the included NOTICE for copyright information and
* LICENSE-APACHE for a copy of the license.
*/
#include <postgres.h>
#include <catalog/pg_type.h>
#include <utils/builtins.h>
#include <utils/timestamp.h>
#include "catalog.h"
#include "metadata.h"
#include "telemetry/uuid.h"
#include "telemetry/telemetry_metadata.h"
#include "scan_iterator.h"
#include "jsonb_utils.h"
#define METADATA_UUID_KEY_NAME "uuid"
#define METADATA_EXPORTED_UUID_KEY_NAME "exported_uuid"
#define METADATA_TIMESTAMP_KEY_NAME "install_timestamp"
/*
* add all entries from _timescaledb_catalog.metadata
*/
void
ts_telemetry_metadata_add_values(JsonbParseState *state)
{
Datum key, value;
bool key_isnull, value_isnull, include_entry;
ScanIterator iterator =
ts_scan_iterator_create(METADATA, AccessShareLock, CurrentMemoryContext);
iterator.ctx.index = catalog_get_index(ts_catalog_get(), METADATA, METADATA_PKEY_IDX);
ts_scanner_foreach(&iterator)
{
TupleInfo *ti = iterator.tinfo;
key = heap_getattr(ti->tuple, Anum_metadata_key, ti->desc, &key_isnull);
include_entry =
!key_isnull &&
DatumGetBool(
heap_getattr(ti->tuple, Anum_metadata_include_in_telemetry, ti->desc, &key_isnull));
if (include_entry)
{
Name key_name = DatumGetName(key);
/* skip keys included as toplevel items */
if (namestrcmp(key_name, METADATA_UUID_KEY_NAME) != 0 &&
namestrcmp(key_name, METADATA_EXPORTED_UUID_KEY_NAME) != 0 &&
namestrcmp(key_name, METADATA_TIMESTAMP_KEY_NAME) != 0)
{
value = heap_getattr(ti->tuple, Anum_metadata_value, ti->desc, &value_isnull);
if (!value_isnull)
ts_jsonb_add_str(state, DatumGetCString(key), TextDatumGetCString(value));
}
}
}
}
static Datum
get_uuid_by_key(const char *key)
{
bool isnull;
Datum uuid;
uuid = ts_metadata_get_value(CStringGetDatum(key), CSTRINGOID, UUIDOID, &isnull);
if (isnull)
uuid = ts_metadata_insert(CStringGetDatum(key),
CSTRINGOID,
UUIDPGetDatum(ts_uuid_create()),
UUIDOID,
true);
return uuid;
}
Datum
ts_telemetry_metadata_get_uuid(void)
{
return get_uuid_by_key(METADATA_UUID_KEY_NAME);
}
Datum
ts_telemetry_metadata_get_exported_uuid(void)
{
return get_uuid_by_key(METADATA_EXPORTED_UUID_KEY_NAME);
}
Datum
ts_telemetry_metadata_get_install_timestamp(void)
{
bool isnull;
Datum timestamp;
timestamp = ts_metadata_get_value(CStringGetDatum(METADATA_TIMESTAMP_KEY_NAME),
CSTRINGOID,
TIMESTAMPTZOID,
&isnull);
if (isnull)
timestamp = ts_metadata_insert(CStringGetDatum(METADATA_TIMESTAMP_KEY_NAME),
CSTRINGOID,
TimestampTzGetDatum(GetCurrentTimestamp()),
TIMESTAMPTZOID,
true);
return timestamp;
}

View File

@ -0,0 +1,17 @@
/*
* This file and its contents are licensed under the Apache License 2.0.
* Please see the included NOTICE for copyright information and
* LICENSE-APACHE for a copy of the license.
*/
#ifndef TIMESCALEDB_TELEMETRY_TELEMETRY_METADATA_H
#define TIMESCALEDB_TELEMETRY_TELEMETRY_METADATA_H
#include <postgres.h>
#include <utils/jsonb.h>
extern void ts_telemetry_metadata_add_values(JsonbParseState *state);
extern Datum ts_telemetry_metadata_get_uuid(void);
extern Datum ts_telemetry_metadata_get_exported_uuid(void);
extern Datum ts_telemetry_metadata_get_install_timestamp(void);
#endif /* TIMESCALEDB_TELEMETRY_TELEMETRY_METADATA_H */

View File

@ -1,16 +0,0 @@
/*
* This file and its contents are licensed under the Apache License 2.0.
* Please see the included NOTICE for copyright information and
* LICENSE-APACHE for a copy of the license.
*/
#ifndef TIMESCALEDB_TELEMETRY_METADATA_H
#define TIMESCALEDB_TELEMETRY_METADATA_H
#include <postgres.h>
extern Datum ts_telemetry_metadata_get_value(Datum metadata_key, Oid key_type, Oid value_type,
bool *isnull);
extern Datum ts_telemetry_metadata_insert(Datum metadata_key, Oid key_type, Datum metadata_value,
Oid value_type);
#endif /* TIMESCALEDB_TELEMETRY_METADATA_H */

View File

@ -204,8 +204,8 @@ SELECT * FROM _timescaledb_catalog.hypertable;
_timescaledb_catalog | dimension | table | super_user _timescaledb_catalog | dimension | table | super_user
_timescaledb_catalog | dimension_slice | table | super_user _timescaledb_catalog | dimension_slice | table | super_user
_timescaledb_catalog | hypertable | table | super_user _timescaledb_catalog | hypertable | table | super_user
_timescaledb_catalog | metadata | table | super_user
_timescaledb_catalog | tablespace | table | super_user _timescaledb_catalog | tablespace | table | super_user
_timescaledb_catalog | telemetry_metadata | table | super_user
(12 rows) (12 rows)
\dt "_timescaledb_internal".* \dt "_timescaledb_internal".*

View File

@ -10,7 +10,7 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.test_install_timestamp() RETURN
AS :MODULE_PATHNAME, 'ts_test_install_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; AS :MODULE_PATHNAME, 'ts_test_install_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER \c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
-- uuid and install_timestamp should already be in the table before we generate -- uuid and install_timestamp should already be in the table before we generate
SELECT COUNT(*) from _timescaledb_catalog.telemetry_metadata; SELECT COUNT(*) from _timescaledb_catalog.metadata;
count count
------- -------
2 2
@ -20,20 +20,20 @@ SELECT _timescaledb_internal.test_uuid() as uuid_1 \gset
SELECT _timescaledb_internal.test_exported_uuid() as uuid_ex_1 \gset SELECT _timescaledb_internal.test_exported_uuid() as uuid_ex_1 \gset
SELECT _timescaledb_internal.test_install_timestamp() as timestamp_1 \gset SELECT _timescaledb_internal.test_install_timestamp() as timestamp_1 \gset
-- Check that there is exactly 1 UUID row -- Check that there is exactly 1 UUID row
SELECT COUNT(*) from _timescaledb_catalog.telemetry_metadata where key='uuid'; SELECT COUNT(*) from _timescaledb_catalog.metadata where key='uuid';
count count
------- -------
1 1
(1 row) (1 row)
-- Check that exported_uuid and timestamp are also generated -- Check that exported_uuid and timestamp are also generated
SELECT COUNT(*) from _timescaledb_catalog.telemetry_metadata where key='exported_uuid'; SELECT COUNT(*) from _timescaledb_catalog.metadata where key='exported_uuid';
count count
------- -------
1 1
(1 row) (1 row)
SELECT COUNT(*) from _timescaledb_catalog.telemetry_metadata where key='install_timestamp'; SELECT COUNT(*) from _timescaledb_catalog.metadata where key='install_timestamp';
count count
------- -------
1 1
@ -88,7 +88,7 @@ ALTER DATABASE :TEST_DBNAME SET timescaledb.restoring='on';
ALTER DATABASE :TEST_DBNAME SET timescaledb.restoring='off'; ALTER DATABASE :TEST_DBNAME SET timescaledb.restoring='off';
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER \c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
-- Should have all 3 row, because pg_dump includes the insertion of uuid and timestamp. -- Should have all 3 row, because pg_dump includes the insertion of uuid and timestamp.
SELECT COUNT(*) FROM _timescaledb_catalog.telemetry_metadata; SELECT COUNT(*) FROM _timescaledb_catalog.metadata;
count count
------- -------
3 3

View File

@ -26,7 +26,7 @@ SELECT _timescaledb_internal.test_privacy();
(1 row) (1 row)
-- To make sure nothing was sent, we check the UUID table to make sure no exported UUID row was created -- To make sure nothing was sent, we check the UUID table to make sure no exported UUID row was created
SELECT key from _timescaledb_catalog.telemetry_metadata; SELECT key from _timescaledb_catalog.metadata;
key key
------------------- -------------------
uuid uuid

View File

@ -14,7 +14,8 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.test_validate_server_version(re
CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry_main_conn(text, text) CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry_main_conn(text, text)
RETURNS BOOLEAN AS :MODULE_PATHNAME, 'ts_test_telemetry_main_conn' LANGUAGE C IMMUTABLE PARALLEL SAFE; RETURNS BOOLEAN AS :MODULE_PATHNAME, 'ts_test_telemetry_main_conn' LANGUAGE C IMMUTABLE PARALLEL SAFE;
CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry(host text = NULL, servname text = NULL, port int = NULL) RETURNS JSONB AS :MODULE_PATHNAME, 'ts_test_telemetry' LANGUAGE C IMMUTABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry(host text = NULL, servname text = NULL, port int = NULL) RETURNS JSONB AS :MODULE_PATHNAME, 'ts_test_telemetry' LANGUAGE C IMMUTABLE PARALLEL SAFE;
INSERT INTO _timescaledb_catalog.telemetry_metadata VALUES ('foo','bar'); INSERT INTO _timescaledb_catalog.metadata VALUES ('foo','bar',TRUE);
INSERT INTO _timescaledb_catalog.metadata VALUES ('bar','baz',FALSE);
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER \c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
SELECT _timescaledb_internal.test_status_ssl(200); SELECT _timescaledb_internal.test_status_ssl(200);
test_status_ssl test_status_ssl
@ -317,7 +318,7 @@ SELECT json_object_field(get_telemetry_report()::json,'num_continuous_aggs');
"0" "0"
(1 row) (1 row)
-- check telemetry picks up content from telemetry_metadata -- check telemetry picks up flagged content from metadata
SELECT json_object_field(get_telemetry_report()::json,'db_metadata'); SELECT json_object_field(get_telemetry_report()::json,'db_metadata');
json_object_field json_object_field
------------------- -------------------

View File

@ -85,8 +85,8 @@ if (CMAKE_BUILD_TYPE MATCHES Debug)
bgw_launcher.sql bgw_launcher.sql
bgw_db_scheduler.sql bgw_db_scheduler.sql
c_unit_tests.sql c_unit_tests.sql
telemetry_metadata.sql
loader.sql loader.sql
metadata.sql
multi_transaction_index.sql multi_transaction_index.sql
net.sql net.sql
symbol_conflict.sql symbol_conflict.sql

View File

@ -12,17 +12,17 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.test_install_timestamp() RETURN
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER \c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
-- uuid and install_timestamp should already be in the table before we generate -- uuid and install_timestamp should already be in the table before we generate
SELECT COUNT(*) from _timescaledb_catalog.telemetry_metadata; SELECT COUNT(*) from _timescaledb_catalog.metadata;
SELECT _timescaledb_internal.test_uuid() as uuid_1 \gset SELECT _timescaledb_internal.test_uuid() as uuid_1 \gset
SELECT _timescaledb_internal.test_exported_uuid() as uuid_ex_1 \gset SELECT _timescaledb_internal.test_exported_uuid() as uuid_ex_1 \gset
SELECT _timescaledb_internal.test_install_timestamp() as timestamp_1 \gset SELECT _timescaledb_internal.test_install_timestamp() as timestamp_1 \gset
-- Check that there is exactly 1 UUID row -- Check that there is exactly 1 UUID row
SELECT COUNT(*) from _timescaledb_catalog.telemetry_metadata where key='uuid'; SELECT COUNT(*) from _timescaledb_catalog.metadata where key='uuid';
-- Check that exported_uuid and timestamp are also generated -- Check that exported_uuid and timestamp are also generated
SELECT COUNT(*) from _timescaledb_catalog.telemetry_metadata where key='exported_uuid'; SELECT COUNT(*) from _timescaledb_catalog.metadata where key='exported_uuid';
SELECT COUNT(*) from _timescaledb_catalog.telemetry_metadata where key='install_timestamp'; SELECT COUNT(*) from _timescaledb_catalog.metadata where key='install_timestamp';
-- Make sure that the UUID is idempotent -- Make sure that the UUID is idempotent
SELECT _timescaledb_internal.test_uuid() = :'uuid_1' as uuids_equal; SELECT _timescaledb_internal.test_uuid() = :'uuid_1' as uuids_equal;
@ -47,7 +47,7 @@ ALTER DATABASE :TEST_DBNAME SET timescaledb.restoring='off';
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER \c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
-- Should have all 3 row, because pg_dump includes the insertion of uuid and timestamp. -- Should have all 3 row, because pg_dump includes the insertion of uuid and timestamp.
SELECT COUNT(*) FROM _timescaledb_catalog.telemetry_metadata; SELECT COUNT(*) FROM _timescaledb_catalog.metadata;
-- Verify that this is the old exported_uuid -- Verify that this is the old exported_uuid
SELECT _timescaledb_internal.test_exported_uuid() = :'uuid_ex_1' as exported_uuids_equal; SELECT _timescaledb_internal.test_exported_uuid() = :'uuid_ex_1' as exported_uuids_equal;
-- Verify that the uuid and timestamp are new -- Verify that the uuid and timestamp are new

View File

@ -13,4 +13,4 @@ SET timescaledb.telemetry_level=off;
SHOW timescaledb.telemetry_level; SHOW timescaledb.telemetry_level;
SELECT _timescaledb_internal.test_privacy(); SELECT _timescaledb_internal.test_privacy();
-- To make sure nothing was sent, we check the UUID table to make sure no exported UUID row was created -- To make sure nothing was sent, we check the UUID table to make sure no exported UUID row was created
SELECT key from _timescaledb_catalog.telemetry_metadata; SELECT key from _timescaledb_catalog.metadata;

View File

@ -16,7 +16,8 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry_main_conn(text,
RETURNS BOOLEAN AS :MODULE_PATHNAME, 'ts_test_telemetry_main_conn' LANGUAGE C IMMUTABLE PARALLEL SAFE; RETURNS BOOLEAN AS :MODULE_PATHNAME, 'ts_test_telemetry_main_conn' LANGUAGE C IMMUTABLE PARALLEL SAFE;
CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry(host text = NULL, servname text = NULL, port int = NULL) RETURNS JSONB AS :MODULE_PATHNAME, 'ts_test_telemetry' LANGUAGE C IMMUTABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry(host text = NULL, servname text = NULL, port int = NULL) RETURNS JSONB AS :MODULE_PATHNAME, 'ts_test_telemetry' LANGUAGE C IMMUTABLE PARALLEL SAFE;
INSERT INTO _timescaledb_catalog.telemetry_metadata VALUES ('foo','bar'); INSERT INTO _timescaledb_catalog.metadata VALUES ('foo','bar',TRUE);
INSERT INTO _timescaledb_catalog.metadata VALUES ('bar','baz',FALSE);
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER \c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
SELECT _timescaledb_internal.test_status_ssl(200); SELECT _timescaledb_internal.test_status_ssl(200);
@ -128,7 +129,7 @@ WHERE key != 'os_name_pretty';
SELECT json_object_field(get_telemetry_report()::json,'num_continuous_aggs'); SELECT json_object_field(get_telemetry_report()::json,'num_continuous_aggs');
-- check telemetry picks up content from telemetry_metadata -- check telemetry picks up flagged content from metadata
SELECT json_object_field(get_telemetry_report()::json,'db_metadata'); SELECT json_object_field(get_telemetry_report()::json,'db_metadata');
-- check timescaledb_telemetry.cloud -- check timescaledb_telemetry.cloud

View File

@ -10,7 +10,7 @@
#include <utils/builtins.h> #include <utils/builtins.h>
#include "export.h" #include "export.h"
#include "telemetry/metadata.h" #include "telemetry/telemetry_metadata.h"
TS_FUNCTION_INFO_V1(ts_test_uuid); TS_FUNCTION_INFO_V1(ts_test_uuid);
TS_FUNCTION_INFO_V1(ts_test_exported_uuid); TS_FUNCTION_INFO_V1(ts_test_exported_uuid);
@ -19,18 +19,18 @@ TS_FUNCTION_INFO_V1(ts_test_install_timestamp);
Datum Datum
ts_test_uuid(PG_FUNCTION_ARGS) ts_test_uuid(PG_FUNCTION_ARGS)
{ {
PG_RETURN_DATUM(ts_metadata_get_uuid()); PG_RETURN_DATUM(ts_telemetry_metadata_get_uuid());
} }
Datum Datum
ts_test_exported_uuid(PG_FUNCTION_ARGS) ts_test_exported_uuid(PG_FUNCTION_ARGS)
{ {
PG_RETURN_DATUM(ts_metadata_get_exported_uuid()); PG_RETURN_DATUM(ts_telemetry_metadata_get_exported_uuid());
} }
Datum Datum
ts_test_install_timestamp(PG_FUNCTION_ARGS) ts_test_install_timestamp(PG_FUNCTION_ARGS)
{ {
PG_RETURN_DATUM(ts_metadata_get_install_timestamp()); PG_RETURN_DATUM(ts_telemetry_metadata_get_install_timestamp());
} }