Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Python API for setting check metadata #4234

Merged
merged 1 commit into from
Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions pkg/collector/python/datadog_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/DataDog/datadog-agent/pkg/config"
"github.com/DataDog/datadog-agent/pkg/metadata/externalhost"
"github.com/DataDog/datadog-agent/pkg/metadata/inventories"
"github.com/DataDog/datadog-agent/pkg/util"
"github.com/DataDog/datadog-agent/pkg/util/kubernetes/clustername"
"github.com/DataDog/datadog-agent/pkg/util/log"
Expand Down Expand Up @@ -150,3 +151,14 @@ func SetExternalTags(hostname *C.char, sourceType *C.char, tags **C.char) {

externalhost.SetExternalTags(hname, stype, tagsStrings)
}

// SetCheckMetadata updates a metadata value for one check instance in the cache.
// Indirectly used by the C function `set_check_metadata` that's mapped to `datadog_agent.set_check_metadata`.
//export SetCheckMetadata
func SetCheckMetadata(checkID, name, value *C.char) {
cid := C.GoString(checkID)
key := C.GoString(name)
val := C.GoString(value)

inventories.SetCheckMetadata(cid, key, val)
}
2 changes: 2 additions & 0 deletions pkg/collector/python/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ void GetConfig(char*, char **);
void GetHostname(char **);
void GetVersion(char **);
void Headers(char **);
void SetCheckMetadata(char *, char *, char *);
void SetExternalTags(char *, char *, char **);
bool TracemallocEnabled();

Expand All @@ -90,6 +91,7 @@ void initDatadogAgentModule(rtloader_t *rtloader) {
set_get_hostname_cb(rtloader, GetHostname);
set_get_version_cb(rtloader, GetVersion);
set_headers_cb(rtloader, Headers);
set_set_check_metadata_cb(rtloader, SetCheckMetadata);
set_set_external_tags_cb(rtloader, SetExternalTags);
set_tracemalloc_enabled_cb(rtloader, TracemallocEnabled);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
enhancements:
- |
Implement API that allows Python checks to send metadata using
the ``inventories`` provider.
43 changes: 43 additions & 0 deletions rtloader/common/builtins/datadog_agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ static cb_get_hostname_t cb_get_hostname = NULL;
static cb_tracemalloc_enabled_t cb_tracemalloc_enabled = NULL;
static cb_get_version_t cb_get_version = NULL;
static cb_headers_t cb_headers = NULL;
static cb_set_check_metadata_t cb_set_check_metadata = NULL;
static cb_set_external_tags_t cb_set_external_tags = NULL;

// forward declarations
Expand All @@ -26,6 +27,7 @@ static PyObject *tracemalloc_enabled(PyObject *self, PyObject *args);
static PyObject *get_version(PyObject *self, PyObject *args);
static PyObject *headers(PyObject *self, PyObject *args, PyObject *kwargs);
static PyObject *log_message(PyObject *self, PyObject *args);
static PyObject *set_check_metadata(PyObject *self, PyObject *args);
static PyObject *set_external_tags(PyObject *self, PyObject *args);

static PyMethodDef methods[] = {
Expand All @@ -36,6 +38,7 @@ static PyMethodDef methods[] = {
{ "get_version", get_version, METH_NOARGS, "Get Agent version." },
{ "headers", (PyCFunction)headers, METH_VARARGS | METH_KEYWORDS, "Get standard set of HTTP headers." },
{ "log", log_message, METH_VARARGS, "Log a message through the agent logger." },
{ "set_check_metadata", set_check_metadata, METH_VARARGS, "Send metadata for Checks." },
{ "set_external_tags", set_external_tags, METH_VARARGS, "Send external host tags." },
{ NULL, NULL } // guards
};
Expand Down Expand Up @@ -82,6 +85,11 @@ void _set_get_clustername_cb(cb_get_clustername_t cb)
cb_get_clustername = cb;
}

void _set_set_check_metadata_cb(cb_set_check_metadata_t cb)
{
cb_set_check_metadata = cb;
}

void _set_set_external_tags_cb(cb_set_external_tags_t cb)
{
cb_set_external_tags = cb;
Expand Down Expand Up @@ -349,6 +357,41 @@ static PyObject *log_message(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}

/*! \fn PyObject *set_check_metadata(PyObject *self, PyObject *args)
\brief This function implements the `datadog_agent.set_check_metadata` method, updating
the value in the cache.
\param self A PyObject* pointer to the `datadog_agent` module.
\param args A PyObject* pointer to a 3-ary tuple containing the unique ID of a check
instance, the name of the metadata entry, and the value of said entry.
\return A PyObject* pointer to `None`.

This function is callable as the `datadog_agent.set_check_metadata` Python method and
uses the `cb_set_check_metadata()` callback to retrieve the value from the agent
with CGO. If the callback has not been set `None` will be returned.
*/
static PyObject *set_check_metadata(PyObject *self, PyObject *args)
{
// callback must be set
if (cb_set_check_metadata == NULL) {
Py_RETURN_NONE;
}

char *check_id, *name, *value;

PyGILState_STATE gstate = PyGILState_Ensure();

// datadog_agent.set_check_metadata(check_id, name, value)
if (!PyArg_ParseTuple(args, "sss", &check_id, &name, &value)) {
PyGILState_Release(gstate);
return NULL;
}

PyGILState_Release(gstate);
cb_set_check_metadata(check_id, name, value);

Py_RETURN_NONE;
}

//
/*! \fn PyObject *set_external_tags(PyObject *self, PyObject *args)
\brief This function implements the `datadog_agent.set_external_tags` method,
Expand Down
9 changes: 9 additions & 0 deletions rtloader/common/builtins/datadog_agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@

The callback is expected to be provided by the rtloader caller - in go-context: CGO.
*/
/*! \fn void _set_set_check_metadata_cb(cb_set_check_metadata_t)
\brief Sets a callback to be used by rtloader to allow setting metadata for a given
check instance.
\param object A function pointer with cb_set_check_metadata_t prototype to the callback
function.

The callback is expected to be provided by the rtloader caller - in go-context: CGO.
*/
/*! \fn void _set_set_external_tags_cb(cb_set_external_tags_t)
\brief Sets a callback to be used by rtloader to allow setting external tags for a given
hostname.
Expand Down Expand Up @@ -118,6 +126,7 @@ void _set_tracemalloc_enabled_cb(cb_tracemalloc_enabled_t);
void _set_get_version_cb(cb_get_version_t);
void _set_headers_cb(cb_headers_t);
void _set_log_cb(cb_log_t);
void _set_set_check_metadata_cb(cb_set_check_metadata_t);
void _set_set_external_tags_cb(cb_set_external_tags_t);

PyObject *_public_headers(PyObject *self, PyObject *args, PyObject *kwargs);
Expand Down
11 changes: 11 additions & 0 deletions rtloader/include/datadog_agent_rtloader.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,17 @@ DATADOG_AGENT_RTLOADER_API void set_tracemalloc_enabled_cb(rtloader_t *, cb_trac
*/
DATADOG_AGENT_RTLOADER_API void set_log_cb(rtloader_t *, cb_log_t);

/*! \fn void set_set_check_metadata_cb(rtloader_t *, cb_set_check_metadata_t)
\brief Sets a callback to be used by rtloader to allow setting metadata for a given
check instance.
\param rtloader_t A rtloader_t * pointer to the RtLoader instance.
\param object A function pointer with cb_set_check_metadata_t prototype to the callback
function.

The callback is expected to be provided by the rtloader caller - in go-context: CGO.
*/
DATADOG_AGENT_RTLOADER_API void set_set_check_metadata_cb(rtloader_t *, cb_set_check_metadata_t);

/*! \fn void set_set_external_tags_cb(rtloader_t *, cb_set_external_tags_t)
\brief Sets a callback to be used by rtloader to allow setting external tags for a given
hostname.
Expand Down
9 changes: 9 additions & 0 deletions rtloader/include/rtloader.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,15 @@ class RtLoader
*/
virtual void setLogCb(cb_log_t) = 0;

//! setCheckMetadataCb member.
/*!
\param A cb_set_check_metadata_t function pointer to the CGO callback.

This allows us to set the relevant CGO callback that will allow adding metadata for
specific check instances to the go-land Inventories metadata provider cache.
*/
virtual void setSetCheckMetadataCb(cb_set_check_metadata_t) = 0;

//! setExternalTagsCb member.
/*!
\param A cb_set_external_tags_t function pointer to the CGO callback.
Expand Down
2 changes: 2 additions & 0 deletions rtloader/include/rtloader_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ typedef void (*cb_get_clustername_t)(char **);
typedef bool (*cb_tracemalloc_enabled_t)(void);
// (message, level)
typedef void (*cb_log_t)(const char *, int);
// (check_id, name, value)
typedef void (*cb_set_check_metadata_t)(char *, char *, char *);
// (hostname, source_type_name, list of tags)
typedef void (*cb_set_external_tags_t)(char *, char *, char **);

Expand Down
5 changes: 5 additions & 0 deletions rtloader/rtloader/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,11 @@ void set_log_cb(rtloader_t *rtloader, cb_log_t cb)
AS_TYPE(RtLoader, rtloader)->setLogCb(cb);
}

void set_set_check_metadata_cb(rtloader_t *rtloader, cb_set_check_metadata_t cb)
{
AS_TYPE(RtLoader, rtloader)->setSetCheckMetadataCb(cb);
}

void set_set_external_tags_cb(rtloader_t *rtloader, cb_set_external_tags_t cb)
{
AS_TYPE(RtLoader, rtloader)->setSetExternalTagsCb(cb);
Expand Down
14 changes: 14 additions & 0 deletions rtloader/test/datadog_agent/datadog_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
// extern bool getTracemallocEnabled();
// extern void getVersion(char **);
// extern void headers(char **);
// extern void setCheckMetadata(char*, char*, char*);
// extern void setExternalHostTags(char*, char*, char**);
//
// static void initDatadogAgentTests(rtloader_t *rtloader) {
Expand All @@ -36,6 +37,7 @@ import (
// set_get_version_cb(rtloader, getVersion);
// set_headers_cb(rtloader, headers);
// set_log_cb(rtloader, doLog);
// set_set_check_metadata_cb(rtloader, setCheckMetadata);
// set_set_external_tags_cb(rtloader, setExternalHostTags);
// }
import "C"
Expand Down Expand Up @@ -163,6 +165,18 @@ func doLog(msg *C.char, level C.int) {
ioutil.WriteFile(tmpfile.Name(), data, 0644)
}

//export setCheckMetadata
func setCheckMetadata(checkID, name, value *C.char) {
cid := C.GoString(checkID)
key := C.GoString(name)
val := C.GoString(value)

f, _ := os.OpenFile(tmpfile.Name(), os.O_APPEND|os.O_RDWR|os.O_CREATE, 0666)
defer f.Close()

f.WriteString(strings.Join([]string{cid, key, val}, ","))
}

//export setExternalHostTags
func setExternalHostTags(hostname *C.char, sourceType *C.char, tags **C.char) {
hname := C.GoString(hostname)
Expand Down
13 changes: 13 additions & 0 deletions rtloader/test/datadog_agent/datadog_agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,19 @@ func TestLog(t *testing.T) {
}
}

func TestSetCheckMetadata(t *testing.T) {
code := `
datadog_agent.set_check_metadata("redis:test:12345", "version.raw", "5.0.6")
`
out, err := run(code)
if err != nil {
t.Fatal(err)
}
if out != "redis:test:12345,version.raw,5.0.6" {
t.Errorf("Unexpected printed value: '%s'", out)
}
}

func TestSetExternalTags(t *testing.T) {
code := `
tags = [
Expand Down
5 changes: 5 additions & 0 deletions rtloader/three/three.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,11 @@ void Three::setLogCb(cb_log_t cb)
_set_log_cb(cb);
}

void Three::setSetCheckMetadataCb(cb_set_check_metadata_t cb)
{
_set_set_check_metadata_cb(cb);
}

void Three::setSetExternalTagsCb(cb_set_external_tags_t cb)
{
_set_set_external_tags_cb(cb);
Expand Down
1 change: 1 addition & 0 deletions rtloader/three/three.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class Three : public RtLoader
void setGetClusternameCb(cb_get_clustername_t);
void setGetTracemallocEnabledCb(cb_tracemalloc_enabled_t);
void setLogCb(cb_log_t);
void setSetCheckMetadataCb(cb_set_check_metadata_t);
void setSetExternalTagsCb(cb_set_external_tags_t);

// _util API
Expand Down
5 changes: 5 additions & 0 deletions rtloader/two/two.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,11 @@ void Two::setLogCb(cb_log_t cb)
_set_log_cb(cb);
}

void Two::setSetCheckMetadataCb(cb_set_check_metadata_t cb)
{
_set_set_check_metadata_cb(cb);
}

void Two::setSetExternalTagsCb(cb_set_external_tags_t cb)
{
_set_set_external_tags_cb(cb);
Expand Down
1 change: 1 addition & 0 deletions rtloader/two/two.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class Two : public RtLoader
void setGetClusternameCb(cb_get_clustername_t);
void setGetTracemallocEnabledCb(cb_tracemalloc_enabled_t);
void setLogCb(cb_log_t);
void setSetCheckMetadataCb(cb_set_check_metadata_t);
void setSetExternalTagsCb(cb_set_external_tags_t);

// _util API
Expand Down