diff --git a/meson.build b/meson.build
index 16eae66..345de5f 100644
--- a/meson.build
+++ b/meson.build
@@ -72,6 +72,7 @@ pycsh_sources = [
'src/wrapper/spaceboot_py.c',
'src/wrapper/param_list_py.c',
'src/wrapper/vmem_client_py.c',
+ 'src/wrapper/victoria_metrics_py.c',
# Utilities
'src/utils.c',
diff --git a/pycsh.pyi b/pycsh.pyi
index ae70f1e..ee868fc 100644
--- a/pycsh.pyi
+++ b/pycsh.pyi
@@ -690,6 +690,19 @@ def sps(from: int, to: int, filename: str, node: int = None, window: int = None,
:raises ProgramDiffError: See class docstring.
"""
+def vm_start(logfile: int = 0, username: str = None, password: str = None, pyargs: dict = None):
+ """Starts victoria metrics thread
+
+ Args:
+ logfile (int, optional): _description_. Defaults to 0.
+ username (str, optional): Username for vm. Defaults to None.
+ password (str, optional): Password for vm. Defaults to None.
+ pyargs (dict, optional): _description_. Defaults to None.
+ """
+
+def vm_stop():
+ """Stops victoria metrics thread"""
+
def csp_init(host: str = None, model: str = None, revision: str = None, version: int = 2, dedup: int = 3) -> None:
"""
Initialize CSP
diff --git a/src/csh/victoria_metrics.c b/src/csh/victoria_metrics.c
index a72c7a1..87c1964 100644
--- a/src/csh/victoria_metrics.c
+++ b/src/csh/victoria_metrics.c
@@ -20,28 +20,15 @@
#include
#include
#include "param_sniffer.h"
+#include "victoria_metrics.h"
static pthread_t vm_push_thread;
int vm_running = 0;
-#define SERVER_PORT 8428
-#define SERVER_PORT_AUTH 8427
-#define BUFFER_SIZE 10 * 1024 * 1024
-
static char buffer[BUFFER_SIZE];
static size_t buffer_size = 0;
static pthread_mutex_t buffer_mutex = PTHREAD_MUTEX_INITIALIZER;
-typedef struct {
- int use_ssl;
- int port;
- int skip_verify;
- int verbose;
- char * username;
- char * password;
- char * server_ip;
-} vm_args;
-
static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata) {
return size * nmemb;
}
diff --git a/src/csh/victoria_metrics.h b/src/csh/victoria_metrics.h
index 9a33098..b8f0630 100644
--- a/src/csh/victoria_metrics.h
+++ b/src/csh/victoria_metrics.h
@@ -10,3 +10,19 @@
void vm_add(char * metric_line);
void vm_add_param(param_t * param);
+
+#define SERVER_PORT 8428
+#define SERVER_PORT_AUTH 8427
+#define BUFFER_SIZE 10 * 1024 * 1024
+
+typedef struct {
+ int use_ssl;
+ int port;
+ int skip_verify;
+ int verbose;
+ char * username;
+ char * password;
+ char * server_ip;
+} vm_args;
+
+void * vm_push(void * arg);
\ No newline at end of file
diff --git a/src/pycsh.c b/src/pycsh.c
index 055f1e8..5b00a66 100644
--- a/src/pycsh.c
+++ b/src/pycsh.c
@@ -68,6 +68,7 @@
#include "wrapper/csp_init_py.h"
#include "wrapper/param_list_py.h"
#include "wrapper/vmem_client_py.h"
+#include "wrapper/victoria_metrics_py.h"
extern const char *version_string;
@@ -249,6 +250,10 @@ static PyMethodDef methods[] = {
{"node", pycsh_slash_node, METH_VARARGS, "Used to get or change the default node."},
{"timeout", pycsh_slash_timeout, METH_VARARGS, "Used to get or change the default timeout."},
{"queue", pycsh_param_cmd, METH_NOARGS, "Print the current command."},
+
+ /* Victoria Metrics */
+ {"vm_start", (PyCFunction)pycsh_vm_start, METH_VARARGS | METH_KEYWORDS, "Starts the victoria metrics thread."},
+ {"vm_stop", (PyCFunction)pycsh_vm_stop, METH_VARARGS | METH_KEYWORDS, "Stops the victoria metrics thread."},
/* Converted CSH commands from libparam/src/param/list/param_list_slash.c */
{"list", (PyCFunction)pycsh_param_list, METH_VARARGS | METH_KEYWORDS, "List all known parameters."},
diff --git a/src/utils.c b/src/utils.c
index c0cca76..19120b7 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -18,6 +18,7 @@
#include "parameter/parameterarray.h"
#include "parameter/pythonparameter.h"
#include "parameter/parameterlist.h"
+#include "../src/csh/victoria_metrics.h"
/* __attribute__(()) doesn't like to treat char** and void** interchangeably. */
diff --git a/src/wrapper/victoria_metrics_py.c b/src/wrapper/victoria_metrics_py.c
new file mode 100644
index 0000000..0f1283c
--- /dev/null
+++ b/src/wrapper/victoria_metrics_py.c
@@ -0,0 +1,166 @@
+/*
+ * param_list_py.c
+ *
+ * Wrappers for lib/param/src/param/list/param_list_slash.c
+ *
+ */
+
+#define PY_SSIZE_T_CLEAN
+#include
+
+#include
+#include
+#include
+#include "../pycsh.h"
+#include "../utils.h"
+#include "../parameter/parameter.h"
+#include "../parameter/pythonparameter.h"
+#include "../src/csh/victoria_metrics.h"
+
+#include "victoria_metrics_py.h"
+
+static pthread_t vm_push_thread;
+extern int vm_running;
+
+static int pycsh_parse_vm_args(PyObject * args_in, vm_args * args_out) {
+ assert(args_in != NULL);
+
+ // Get all the values from the python dict. Everything is a string when it comes from python.
+ PyObject * py_use_ssl = PyDict_GetItemString(args_in, "use_ssl");
+ PyObject * py_port = PyDict_GetItemString(args_in, "port");
+ PyObject * py_skip_verify = PyDict_GetItemString(args_in, "skip_verify");
+ PyObject * py_verbose = PyDict_GetItemString(args_in, "verbose");
+ PyObject * py_server_ip = PyDict_GetItemString(args_in, "server_ip");
+
+ // Check if long characters are larger than INT_MAX since we actually want them to be ints and not longs.
+ // These values are not required, so if the input is NULL we initialize them to 0.
+ long use_ssl;
+ if(py_use_ssl == NULL){
+ use_ssl = 0;
+ } else if (PyLong_Check(py_use_ssl)){
+ use_ssl = PyLong_AsLong(py_use_ssl);
+ if(use_ssl > INT_MAX){
+ PyErr_SetString(PyExc_TypeError, "use_ssl value greater than INT_MAX");
+ return -1;
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError, "TypeError.");
+ return -1;
+ }
+
+ long port;
+ if(py_port == NULL){
+ port = 0;
+ } else if (PyLong_Check(py_port)){
+ port = PyLong_AsLong(py_port);
+ if(port > INT_MAX){
+ PyErr_SetString(PyExc_TypeError, "port value greater than INT_MAX");
+ return -1;
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError, "TypeError.");
+ return -1;
+ }
+
+ long skip_verify;
+ if(py_skip_verify == NULL){
+ skip_verify = 0;
+ } else if (PyLong_Check(py_skip_verify)){
+ skip_verify = PyLong_AsLong(py_skip_verify);
+ if(skip_verify > INT_MAX){
+ PyErr_SetString(PyExc_TypeError, "skip_verify value greater than INT_MAX");
+ return -1;
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError, "TypeError.");
+ return -1;
+ }
+
+ long verbose;
+ if(py_verbose == NULL){
+ verbose = 0;
+ } else if (PyLong_Check(py_verbose)){
+ verbose = PyLong_AsLong(py_verbose);
+ if(verbose > INT_MAX){
+ PyErr_SetString(PyExc_TypeError, "verbose value greater than INT_MAX");
+ return -1;
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError, "TypeError.");
+ return -1;
+ }
+
+ // Server_ip is required, so we make sure it exists.
+ if(!py_server_ip){
+ PyErr_SetString(PyExc_KeyError, "server_ip field missing.");
+ return -1;
+ }
+ if(!PyUnicode_Check(py_server_ip)){
+ PyErr_SetString(PyExc_TypeError, "TypeError in field server_ip.");
+ return -1;
+ }
+ char * server_ip = strdup(PyUnicode_AsUTF8(py_server_ip));
+
+ // Set values in the vm_args struct.
+ args_out->use_ssl = (int)use_ssl;
+ args_out->port = (int)port;
+ args_out->skip_verify = (int)skip_verify;
+ args_out->verbose = (int)verbose;
+
+ args_out->server_ip = server_ip;
+
+ return 0;
+
+}
+
+PyObject * pycsh_vm_start(PyObject * self, PyObject * args, PyObject * kwds) {
+ if(vm_running){
+ printf("Thread already running.\n");
+ return Py_None;
+ }
+
+ int logfile = 0;
+ char * tmp_username = NULL;
+ char * tmp_password = NULL;
+ PyObject * pyargs = NULL;
+
+ static char *kwlist[] = {"logfile", "username", "password", "args", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|issO", kwlist, &logfile, &tmp_username, &tmp_password, &pyargs)) {
+ return NULL;
+ }
+
+ vm_args * vmargs = calloc(1, sizeof(vm_args));
+
+ if(pycsh_parse_vm_args(pyargs, vmargs) < 0){
+ PyErr_SetString(PyExc_ConnectionError, "Invalid arguments");
+ return NULL;
+ }
+
+ if (tmp_username) {
+ if (!tmp_password) {
+ PyErr_SetString(PyExc_ConnectionError, "Provide password");
+ return NULL;
+ }
+ vmargs->username = strdup(tmp_username);
+ vmargs->password = strdup(tmp_password);
+ if (!vmargs->port) {
+ vmargs->port = SERVER_PORT_AUTH;
+ }
+ } else if (!vmargs->port) {
+ vmargs->port = SERVER_PORT;
+ }
+
+ printf("\n%d\n", vmargs->port);
+ pthread_create(&vm_push_thread, NULL, &vm_push, vmargs);
+ vm_running = 1;
+
+ return Py_None;
+
+}
+
+PyObject * pycsh_vm_stop(PyObject * self, PyObject * args, PyObject * kwds) {
+ if(!vm_running) return Py_None;
+ vm_running = 0;
+ return Py_None;
+}
diff --git a/src/wrapper/victoria_metrics_py.h b/src/wrapper/victoria_metrics_py.h
new file mode 100644
index 0000000..369b129
--- /dev/null
+++ b/src/wrapper/victoria_metrics_py.h
@@ -0,0 +1,15 @@
+/*
+ * vm_start_py.c
+ *
+ * Wrappers for lib/param/src/param/list/param_list_slash.c
+ *
+ */
+
+#pragma once
+
+#define PY_SSIZE_T_CLEAN
+#include
+
+PyObject * pycsh_vm_start(PyObject * self, PyObject * args, PyObject * kwds);
+
+PyObject * pycsh_vm_stop(PyObject * self, PyObject * args, PyObject * kwds);
\ No newline at end of file