profile
viewpoint
Sneha Inguva si74 www.snehainguva.com Software engineer @digitalocean. I like to build stuff

digitalocean/captainslog 127

A Syslog Protocol Parser

protochron/k8s-coreos-digitalocean 37

Terraform modules for spinning up a Kubernetes module on DigitalOcean

si74/diyContainer 4

Build your own container

si74/dickdrumpf 3

chrome extension to replace all images of donald trump with dicbutt.

si74/financial-reading-list 1

Resources on personal finance and investing!

si74/about 0

Sourcegraph blog, feature announcements, and website (about.sourcegraph.com)

si74/AlgorithmPractice 0

Just wanted to practice implementing some algorithms

si74/Algorithms 0

This monthly meetup focuses on white boarding algorithms.

si74/animalrescuemap 0

Using mapbox.js and curated data + embedded tweets to represent data from different animal rescue groups

push eventsi74/financial-reading-list

Sneha Inguva

commit sha 9022e30279f123bc92237395b5f895518bd38321

adding two youtube channels

view details

push time in a month

push eventsi74/social-justice-reading

Sneha Inguva

commit sha 21c8e0d4e94b19226fcfb333c9c87c038d14dfe9

adding links on prison abolition

view details

push time in a month

push eventsi74/social-justice-reading

Sneha Inguva

commit sha 8b0c617ab07e25c7921edfee73298ea519158267

adding more speeches

view details

push time in 2 months

push eventsi74/social-justice-reading

Sneha Inguva

commit sha 26c0ae196acd577abdbe3a6544f5e8456b36fa01

adding sources for reparations

view details

push time in 2 months

delete branch si74/financial-reading-list

delete branch : add_investing_by_rose

delete time in 2 months

push eventsi74/financial-reading-list

Sneha Inguva

commit sha 09bc57662ed53014e03735936fa2885a3575f197

add investing with rose channel to finance reading list

view details

Sneha Inguva

commit sha 08fe8722a690c29e8c0c87af8bc4788a47ef4158

Merge pull request #2 from si74/add_investing_by_rose add investing with rose channel to finance reading list

view details

push time in 2 months

create barnchsi74/financial-reading-list

branch : add_investing_by_rose

created branch time in 2 months

push eventsi74/social-justice-reading

Sneha Inguva

commit sha 9384d1ab305fdeafd285c2af040564a6ac78f73a

add the end of policing to the list

view details

push time in 2 months

push eventnetvfy/libnv

Nicolas Bouliane

commit sha 23fce6d0a30b51a19830e36968ae654513da0181

keep a local copy of types definition for now

view details

Sneha Inguva

commit sha 03815fb598a673215364b9f2710fd5b1b4e7b96a

Merge pull request #9 from netvfy/pm keep a local copy of types definition for now

view details

push time in 2 months

PR merged netvfy/libnv

keep a local copy of types definition for now
+4 -0

0 comment

1 changed file

nicboul

pr closed time in 2 months

push eventsi74/social-justice-reading

Sneha Inguva

commit sha 79212e865aaaf4be9e9f01dcaaa8a4b914d3ad8f

adding more revolutionary literature

view details

push time in 2 months

push eventsi74/social-justice-reading

Sneha Inguva

commit sha 3c222669683b45f53dc47763ef5a1e43dd66a5a2

add excellent articles re: social justice reading

view details

push time in 2 months

push eventsi74/social-justice-reading

Sneha Inguva

commit sha 4378ea4c16b473f6538c055cbaf7c685eecd849f

add excellent articles re: social justice reading

view details

push time in 2 months

push eventsi74/social-justice-reading

Sneha Inguva

commit sha 95cc91a5881e93a3a91537a5de3f2b74276a1e57

add excellent articles re: social justice reading

view details

push time in 2 months

push eventsi74/social-justice-reading

Sneha Inguva

commit sha beab246e9e92b21b6a5add46972e1e687dfb7c13

add excellent articles re: social justice reading

view details

push time in 2 months

push eventsi74/social-justice-reading

Sneha Inguva

commit sha c39f9b68fafde753a9a2441b023a70850c819927

add excellent articles re: social justice reading

view details

push time in 2 months

push eventsi74/social-justice-reading

Sneha Inguva

commit sha 0f09f724e3de6712fa3ffe2a7d8ac3e4e5681c4a

add excellent articles re: social justice reading

view details

push time in 2 months

push eventsi74/social-justice-reading

Sneha Inguva

commit sha df6c16ced47a4f53593a708bb2dfe15fafc572bc

add excellent articles re: social justice reading

view details

push time in 2 months

push eventsi74/social-justice-reading

Sneha Inguva

commit sha e710f85869972bed111c0004891290519f677062

add excellent articles re: social justice reading

view details

push time in 2 months

create barnchsi74/social-justice-reading

branch : master

created branch time in 2 months

created repositorysi74/social-justice-reading

A list of excellent books and articles on race and social justice.

created time in 2 months

push eventsi74/financial-reading-list

Sneha Inguva

commit sha f1461378cc12c766c3c42ade1d84e4386f283b88

add list of dummies books

view details

Sneha Inguva

commit sha c0ba4809c0a09001c6cc4cf5971c546fa9396e45

Merge pull request #1 from si74/add_new_books add list of dummies books

view details

push time in 2 months

create barnchsi74/financial-reading-list

branch : add_new_books

created branch time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

 pm_metric_get_store(pm_metric *m, va_list *ap1) 	 * the store are taken */ 	match = 0; 	for (i = 0; i < PM_STORE_MAX; i++) {-		if (m->s[i].lblval[0][0] == '\0') {+		if (strlen(m->s[i].lblval[0]) == 0) {

easier to understand!

nicboul

comment created time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

+/*+ * Copyright (c) 2020 Nicolas Bouliane <nicboul@gmail.com>+ *+ * Permission to use, copy, modify, and distribute this software for any+ * purpose with or without fee is hereby granted, provided that the above+ * copyright notice and this permission notice appear in all copies.+ *+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.+ */++#include <stdarg.h>+#include <stdint.h>+#include <stdio.h>+#include <string.h>++#define PM_COUNTER	"counter"+#define PM_GAUGE	"gauge"+#define PM_HISTOGRAM	"histogram"++#define PM_LEN			128+#define PM_LABEL_MAX		5+#define PM_STORE_MAX		5+#define PM_METRIC_MAX		30+#define PM_HIST_BIN_MAX		10++typedef struct {+	char		name[PM_LEN];+	char		help[PM_LEN];+	char		type[PM_LEN];+	char		label[PM_LABEL_MAX][PM_LEN];+	double		bin[PM_HIST_BIN_MAX];+	uint32_t	n_label;	/* number of label for that metric */+	uint32_t	n_bin;		/* number of bin for that histogram */+	uint32_t	n_store;	/* number of store for that metric */+	struct {+		char	lblval[PM_LABEL_MAX][PM_LEN];+		union {+			double		counter;+			double		gauge;+			struct {+				double		sum;+				uint64_t	cnt[PM_HIST_BIN_MAX];+				uint64_t	inf;+			} histogram;+		};+	} s[PM_STORE_MAX];+} pm_metric;++static int		pm_metric_get_store_index(pm_metric *, va_list *);+static int		pm_dump_counter(pm_metric *, char *, const size_t);+static int		pm_dump_gauge(pm_metric *, char *, const size_t);+static int		pm_dump_histogram(pm_metric *, char *, const size_t);+static size_t		pm_dump_label(pm_metric *, uint32_t, char *, const size_t);++static pm_metric	metric[PM_METRIC_MAX];+static uint32_t		n_metric;++/*+ * Returns the store index of a metric by matching the labels and the+ * labels values, if no match is found, an empty store index is returned.+ * If no store is available or an error occurs, -1 is returned.+ *+ * labels: [user][node]+ * -------------------+ * values: [bob][nyc]   <- store 0+ * values: [alice][nyc] <- store 1+ * values: [bob][flo]   <- store 2+ *+ * A metric can have up to PM_STORE_MAX stores.+ */+int+pm_metric_get_store_index(pm_metric *m, va_list *ap1)+{+	va_list		ap;+	uint32_t	i, j;+	int		idx = -1;+	uint32_t	ret;+	uint8_t		match;+	const char	*label;+	char		lbltmp[PM_LABEL_MAX][PM_LEN];++	/* reorder the labels received */+	va_copy(ap, *ap1);+	for (i = 0; i < m->n_label; i++) {+		label = va_arg(ap, const char *);++		for (j = 0; j < m->n_label; j++) {+			if (strcmp(label, m->label[j]) == 0)+				break;+		}+		ret = snprintf(lbltmp[j], sizeof(lbltmp[j]), "\"%s\"",+			va_arg(ap, const char *));+		if (ret < 0 || ret >= sizeof(lbltmp[j])) goto out;+	}++	/* try to find a store where the labels values match,+	 * return a new store otherwise, or an error if all+	 * the store are taken */+	match = 0;+	for (i = 0; i < PM_STORE_MAX; i++) {+		/* skip empty store */+		if (strlen(m->s[i].lblval[0]) == 0) {+			if (idx == -1)+				idx = i;+			continue;+		}+		/* skip if a value doesn't match */+		for (j = 0; j < m->n_label; j++) {+			if (strcmp(m->s[i].lblval[j], lbltmp[j]) != 0)+				break;+		}+		if (j == m->n_label) {+			match = 1;+			idx = i;+			break;+		}+	}++	/* copy the labels values to the new store */+	if (match == 0 && idx != -1) {+		for (i = 0; i < m->n_label; i++) {+			ret = snprintf(m->s[idx].lblval[i],+				sizeof(m->s[idx].lblval[i]), "%s", lbltmp[i]);+			if (ret < 0 || ret >= sizeof(lbltmp[j])) goto out;+		}+		m->n_store++;+	}+out:+	va_end(ap);+	return (idx);+}++/*+ * Returns a pointer to a newly created metric. If an error occurs, NULL is+ * returned. A maximum of PM_METRIC_MAX can be created. This function expect+ * that `name`, `help` and `type` have a maximum lenght of PM_LEN-1. A metric+ * can have a maximum of PM_LABEL_MAX labels and each label can have a maximum+ * lenght of PM_LEN-1.+ */+pm_metric *+pm_metric_add(const char *name, const char *help, const char *type, const uint32_t n_label, ...)+{+	pm_metric	*m = NULL;+	va_list		 args;+	uint32_t	 i, j;+	uint32_t	 ret = 0;++	for (i = 0; i < PM_METRIC_MAX; i++)+		if (strlen(metric[i].name) == 0)+			break;++	if (i == PM_METRIC_MAX)+		goto out;++	va_start(args, n_label);+	for (j = 0; j < n_label && j < PM_LABEL_MAX; j++) {+		ret = snprintf(metric[i].label[j], sizeof(metric[i].label[j]),+			"%s", va_arg(args, const char *));+		if (ret < 0 || ret >= sizeof(metric[i].label[j])) goto out;+	}++	ret = snprintf(metric[i].help, sizeof(metric[i].help), "%s", help);+	if (ret < 0 || ret >= sizeof(metric[i].help)) goto out;++	ret = snprintf(metric[i].type, sizeof(metric[i].type), "%s", type);+	if (ret < 0 || ret >= sizeof(metric[i].type)) goto out;++	ret = snprintf(metric[i].name, sizeof(metric[i].name), "%s", name);+	if (ret < 0 || ret >= sizeof(metric[i].name)) {+		metric[i].name[0] = '\0';+		goto out;+	}++	metric[i].n_label = n_label;+	m = &metric[i];+	n_metric++;+out:+	va_end(args);+	return (m);+}++/*+ * Create the bin values of an histogram. This function expect that every bin+ * received in parameter is of type double. if an error occurs, -1 is returned.+ */+int+pm_metric_bins(pm_metric *m, const uint32_t n_bin, ...)+{+	va_list		args;+	uint32_t	i;+	int		err = -1;++	if (strcmp(m->type, PM_HISTOGRAM) != 0)+		goto out;++	va_start(args, n_bin);+	for (i = 0; i < n_bin && i < PM_HIST_BIN_MAX; i++)+		m->bin[i] = va_arg(args, double);++	m->n_bin = i;+	err = 0;+out:+	va_end(args);+	return (err);+}++/*+ * Add the value passed in argument to the counter. The value added+ * can't be lower than 0. This function expect the metric labels and+ * their value in parameter. If an error occurs, -1 is returned.+ */+int+pm_counter_add(pm_metric *m, const double value, ...)+{+	va_list	ap;+	int	idx;+	int	err = -1;++	if (strcmp(m->type, PM_COUNTER) != 0)+		goto out;++	if (value < 0)+		goto out;++	va_start(ap, value);+	if ((idx = pm_metric_get_store_index(m, &ap)) < 0)+		goto out;++	m->s[idx].counter += value;+	err = 0;+out:+	va_end(ap);+	return (err);+}++/*+ * Set the gauge to the value passed in argument. This function expect+ * the metric labels and their value in parameter. If an error occurs,+ * -1 is returned.+ */+int+pm_gauge_set(pm_metric *m, const double value, ...)+{+	va_list	ap;+	int	idx;+	int	err = -1;++	if (strcmp(m->type, PM_GAUGE) != 0)+		goto out;++	va_start(ap, value);+	if ((idx = pm_metric_get_store_index(m, &ap)) < 0)+		goto out;++	m->s[idx].gauge = value;+	err = 0;+out:+	va_end(ap);+	return (err);+}++/*+ * Add the value received in argument to the gauge. This function expect+ * the metric labels and their value in parameter. If an error occurs,+ * -1 is returned.+ */+int+pm_gauge_add(pm_metric *m, const double value, ...)+{+	va_list	ap;+	int	idx;+	int	err = -1;++	if (strcmp(m->type, PM_GAUGE) != 0)+		goto out;++	va_start(ap, value);+	if ((idx = pm_metric_get_store_index(m, &ap)) < 0)+		goto out;++	m->s[idx].gauge += value;+	err = 0;+out:+	va_end(ap);+	return (err);+}++/* Increase the hitcount of the bin matching the observed. This function expect+ * in parameter the metric labels and their values. If an error occurs,+ * -1 is returned.+ */+int+pm_histogram_observe(pm_metric *m, const double value, ...)+{+	va_list		ap;+	uint32_t	i;+	int		idx;+	int		err = -1;++	if (strcmp(m->type, PM_HISTOGRAM) != 0)+		goto out;++	va_start(ap, value);+	if ((idx = pm_metric_get_store_index(m, &ap)) < 0)+		goto out;++	for (i = 0; i < m->n_bin; i++) {+		if (value <= m->bin[i])+			m->s[idx].histogram.cnt[i]++;+	}+	if (i == m->n_bin)+		m->s[idx].histogram.inf++;++	m->s[idx].histogram.sum += value;+	err = 0;+out:+	va_end(ap);+	return (err);+}++/* Print the counter metric in a buffer. If the return value is greater than+ * or equal to the bufsz argument, the buffer was too short and some of the+ * printed characters were discarded. If an error occurs, -1 is returned.+ */+int+pm_dump_counter(pm_metric *m, char *buf, const size_t bufsz)+{+	uint32_t	i_bin;+	uint32_t	i_store;+	uint32_t	ret = 0, off = 0;++	if (m->n_store == 0)+		goto out;++	for (i_store = 0; i_store < m->n_store; i_store++) {+		if (i_store > 0) {+			ret = snprintf(buf+off, bufsz-off, "\n");+			if (ret < 0 || ret >= bufsz-off) goto error; off += ret;+		}+		ret = snprintf(buf+off, bufsz-off, "%s{", m->name);+		if (ret < 0 || ret >= bufsz-off) goto error; off += ret;++		ret = pm_dump_label(m, i_store, buf+off, bufsz-off);+		if (ret < 0 || ret >= bufsz-off) goto error; off += ret;++		ret = snprintf(buf+off, bufsz-off, "} %f", m->s[i_store].counter);+		if (ret < 0 || ret >= bufsz-off) goto error; off += ret;+	}+out:+	return (off);+error:+	off += ret;+	if (ret < 0)+		off = ret;+	return (off);+}++/* Print the gauge metric in a buffer. If the return value is greater than+ * or equal to the bufsz argument, the buffer was too short and some of the+ * printed characters were discarded. If an error occurs, -1 is returned.+ */+int+pm_dump_gauge(pm_metric *m, char *buf, const size_t bufsz)

love that this is separated out into multiple functions - quite clean!

nicboul

comment created time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

+/*+ * Copyright (c) 2020 Nicolas Bouliane <nicboul@gmail.com>+ *+ * Permission to use, copy, modify, and distribute this software for any+ * purpose with or without fee is hereby granted, provided that the above+ * copyright notice and this permission notice appear in all copies.+ *+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.+ */++#include <stdarg.h>+#include <stdint.h>+#include <stdio.h>+#include <string.h>++#define PM_COUNTER	"counter"+#define PM_GAUGE	"gauge"+#define PM_HISTOGRAM	"histogram"++#define PM_LEN			128+#define PM_LABEL_MAX		5+#define PM_STORE_MAX		5+#define PM_METRIC_MAX		30+#define PM_HIST_BIN_MAX		10++typedef struct {+	char		name[PM_LEN];+	char		help[PM_LEN];+	char		type[PM_LEN];+	char		label[PM_LABEL_MAX][PM_LEN];+	double		bin[PM_HIST_BIN_MAX];+	uint32_t	n_label;	/* number of label for that metric */+	uint32_t	n_bin;		/* number of bin for that histogram */+	uint32_t	n_store;	/* number of store for that metric */+	struct {+		char	lblval[PM_LABEL_MAX][PM_LEN];+		union {+			double		counter;+			double		gauge;+			struct {+				double		sum;+				uint64_t	cnt[PM_HIST_BIN_MAX];+				uint64_t	inf;+			} histogram;+		};+	} s[PM_STORE_MAX];+} pm_metric;++static int		pm_metric_get_store_index(pm_metric *, va_list *);+static int		pm_dump_counter(pm_metric *, char *, const size_t);+static int		pm_dump_gauge(pm_metric *, char *, const size_t);+static int		pm_dump_histogram(pm_metric *, char *, const size_t);+static size_t		pm_dump_label(pm_metric *, uint32_t, char *, const size_t);++static pm_metric	metric[PM_METRIC_MAX];+static uint32_t		n_metric;++/*+ * Returns the store index of a metric by matching the labels and the+ * labels values, if no match is found, an empty store index is returned.+ * If no store is available or an error occurs, -1 is returned.+ *+ * labels: [user][node]+ * -------------------+ * values: [bob][nyc]   <- store 0+ * values: [alice][nyc] <- store 1+ * values: [bob][flo]   <- store 2+ *+ * A metric can have up to PM_STORE_MAX stores.+ */+int+pm_metric_get_store_index(pm_metric *m, va_list *ap1)+{+	va_list		ap;+	uint32_t	i, j;+	int		idx = -1;+	uint32_t	ret;+	uint8_t		match;+	const char	*label;+	char		lbltmp[PM_LABEL_MAX][PM_LEN];++	/* reorder the labels received */+	va_copy(ap, *ap1);+	for (i = 0; i < m->n_label; i++) {+		label = va_arg(ap, const char *);++		for (j = 0; j < m->n_label; j++) {+			if (strcmp(label, m->label[j]) == 0)+				break;+		}+		ret = snprintf(lbltmp[j], sizeof(lbltmp[j]), "\"%s\"",+			va_arg(ap, const char *));+		if (ret < 0 || ret >= sizeof(lbltmp[j])) goto out;+	}++	/* try to find a store where the labels values match,+	 * return a new store otherwise, or an error if all+	 * the store are taken */+	match = 0;+	for (i = 0; i < PM_STORE_MAX; i++) {+		/* skip empty store */+		if (strlen(m->s[i].lblval[0]) == 0) {+			if (idx == -1)+				idx = i;+			continue;+		}+		/* skip if a value doesn't match */+		for (j = 0; j < m->n_label; j++) {+			if (strcmp(m->s[i].lblval[j], lbltmp[j]) != 0)+				break;+		}+		if (j == m->n_label) {+			match = 1;+			idx = i;+			break;+		}+	}++	/* copy the labels values to the new store */+	if (match == 0 && idx != -1) {+		for (i = 0; i < m->n_label; i++) {+			ret = snprintf(m->s[idx].lblval[i],+				sizeof(m->s[idx].lblval[i]), "%s", lbltmp[i]);+			if (ret < 0 || ret >= sizeof(lbltmp[j])) goto out;+		}+		m->n_store++;+	}+out:+	va_end(ap);+	return (idx);+}++/*+ * Returns a pointer to a newly created metric. If an error occurs, NULL is

nit: Creates and returns?

nicboul

comment created time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

+/*+ * Copyright (c) 2020 Nicolas Bouliane <nicboul@gmail.com>+ *+ * Permission to use, copy, modify, and distribute this software for any+ * purpose with or without fee is hereby granted, provided that the above+ * copyright notice and this permission notice appear in all copies.+ *+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.+ */++#include <stdarg.h>+#include <stdint.h>+#include <stdio.h>+#include <string.h>++#define PM_COUNTER	"counter"+#define PM_GAUGE	"gauge"+#define PM_HISTOGRAM	"histogram"++#define PM_LEN			128+#define PM_LABEL_MAX		5+#define PM_STORE_MAX		5+#define PM_METRIC_MAX		30+#define PM_HIST_BIN_MAX		10++typedef struct {+	char		name[PM_LEN];+	char		help[PM_LEN];+	char		type[PM_LEN];+	char		label[PM_LABEL_MAX][PM_LEN];+	double		bin[PM_HIST_BIN_MAX];+	uint32_t	n_label;	/* number of label for that metric */+	uint32_t	n_bin;		/* number of bin for that histogram */+	uint32_t	n_store;	/* number of store for that metric */+	struct {+		char	lblval[PM_LABEL_MAX][PM_LEN];+		union {+			double		counter;+			double		gauge;+			struct {+				double		sum;+				uint64_t	cnt[PM_HIST_BIN_MAX];+				uint64_t	inf;+			} histogram;+		};+	} s[PM_STORE_MAX];+} pm_metric;++static int		pm_metric_get_store_index(pm_metric *, va_list *);+static int		pm_dump_counter(pm_metric *, char *, const size_t);+static int		pm_dump_gauge(pm_metric *, char *, const size_t);+static int		pm_dump_histogram(pm_metric *, char *, const size_t);+static size_t		pm_dump_label(pm_metric *, uint32_t, char *, const size_t);++static pm_metric	metric[PM_METRIC_MAX];+static uint32_t		n_metric;++/*+ * Returns the store index of a metric by matching the labels and the+ * labels values, if no match is found, an empty store index is returned.+ * If no store is available or an error occurs, -1 is returned.+ *+ * labels: [user][node]+ * -------------------+ * values: [bob][nyc]   <- store 0+ * values: [alice][nyc] <- store 1+ * values: [bob][flo]   <- store 2+ *+ * A metric can have up to PM_STORE_MAX stores.+ */+int+pm_metric_get_store_index(pm_metric *m, va_list *ap1)+{+	va_list		ap;+	uint32_t	i, j;+	int		idx = -1;+	uint32_t	ret;+	uint8_t		match;+	const char	*label;+	char		lbltmp[PM_LABEL_MAX][PM_LEN];++	/* reorder the labels received */+	va_copy(ap, *ap1);+	for (i = 0; i < m->n_label; i++) {+		label = va_arg(ap, const char *);++		for (j = 0; j < m->n_label; j++) {+			if (strcmp(label, m->label[j]) == 0)+				break;+		}+		ret = snprintf(lbltmp[j], sizeof(lbltmp[j]), "\"%s\"",+			va_arg(ap, const char *));+		if (ret < 0 || ret >= sizeof(lbltmp[j])) goto out;+	}++	/* try to find a store where the labels values match,+	 * return a new store otherwise, or an error if all+	 * the store are taken */

nit: "or an error if the data store is filled"

nicboul

comment created time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

+/*+ * Copyright (c) 2020 Nicolas Bouliane <nicboul@gmail.com>+ *+ * Permission to use, copy, modify, and distribute this software for any+ * purpose with or without fee is hereby granted, provided that the above+ * copyright notice and this permission notice appear in all copies.+ *+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.+ */++#include <stdarg.h>+#include <stdint.h>+#include <stdio.h>+#include <string.h>++#define PM_COUNTER	"counter"+#define PM_GAUGE	"gauge"+#define PM_HISTOGRAM	"histogram"++#define PM_LEN			128+#define PM_LABEL_MAX		5+#define PM_STORE_MAX		5+#define PM_METRIC_MAX		30+#define PM_HIST_BIN_MAX		10++typedef struct {+	char		name[PM_LEN];+	char		help[PM_LEN];+	char		type[PM_LEN];+	char		label[PM_LABEL_MAX][PM_LEN];+	double		bin[PM_HIST_BIN_MAX];+	uint32_t	n_label;	/* number of label for that metric */+	uint32_t	n_bin;		/* number of bin for that histogram */

nit: number of bins for that histogram

nicboul

comment created time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

+/*+ * Copyright (c) 2020 Nicolas Bouliane <nicboul@gmail.com>+ *+ * Permission to use, copy, modify, and distribute this software for any+ * purpose with or without fee is hereby granted, provided that the above+ * copyright notice and this permission notice appear in all copies.+ *+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.+ */++#include <stdarg.h>+#include <stdint.h>+#include <stdio.h>+#include <string.h>++#define PM_COUNTER	"counter"+#define PM_GAUGE	"gauge"+#define PM_HISTOGRAM	"histogram"++#define PM_LEN			128+#define PM_LABEL_MAX		5+#define PM_STORE_MAX		5+#define PM_METRIC_MAX		30+#define PM_HIST_BIN_MAX		10++typedef struct {+	char		name[PM_LEN];+	char		help[PM_LEN];+	char		type[PM_LEN];+	char		label[PM_LABEL_MAX][PM_LEN];+	double		bin[PM_HIST_BIN_MAX];+	uint32_t	n_label;	/* number of label for that metric */

nit: number of total labels for that metric

nicboul

comment created time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

+/*+ * Copyright (c) 2020 Nicolas Bouliane <nicboul@gmail.com>+ *+ * Permission to use, copy, modify, and distribute this software for any+ * purpose with or without fee is hereby granted, provided that the above+ * copyright notice and this permission notice appear in all copies.+ *+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.+ */++#include <stdarg.h>+#include <stdint.h>+#include <stdio.h>+#include <string.h>++#define PM_COUNTER	"counter"+#define PM_GAUGE	"gauge"+#define PM_HISTOGRAM	"histogram"++#define PM_LEN			128+#define PM_LABEL_MAX		5+#define PM_STORE_MAX		5+#define PM_METRIC_MAX		30+#define PM_HIST_BIN_MAX		10++typedef struct {+	char		name[PM_LEN];+	char		help[PM_LEN];+	char		type[PM_LEN];+	char		label[PM_LABEL_MAX][PM_LEN];+	double		bin[PM_HIST_BIN_MAX];+	uint32_t	n_label;	/* number of label for that metric */+	uint32_t	n_bin;		/* number of bin for that histogram */+	uint32_t	n_store;	/* number of store for that metric */

nit: can this comment be a bit more meaningful? i.e. "number of total stored values for a metric"

nicboul

comment created time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

+#include <stdarg.h>+#include <stdint.h>+#include <stdio.h>+#include <string.h>++#define PM_COUNTER	"counter"+#define PM_GAUGE	"gauge"+#define PM_HISTOGRAM	"histogram"++#define PM_LEN			128+#define PM_LABEL_MAX		5+#define PM_LABEL_VAL_MAX	5+#define PM_METRIC_MAX		30+#define PM_HIST_BIN_MAX		10++typedef struct {+	char		name[PM_LEN];+	char		help[PM_LEN];+	char		type[PM_LEN];+	char		label[PM_LABEL_MAX][PM_LEN];+	uint32_t	n_label;+	double		bin[PM_HIST_BIN_MAX];+	uint32_t	n_bin;

is this just the total bucket number?

nicboul

comment created time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

+#include <stdarg.h>+#include <stdint.h>+#include <stdio.h>+#include <string.h>++#define PM_COUNTER	"counter"+#define PM_GAUGE	"gauge"+#define PM_HISTOGRAM	"histogram"++#define PM_LEN			128+#define PM_LABEL_MAX		5+#define PM_LABEL_VAL_MAX	5+#define PM_METRIC_MAX		30+#define PM_HIST_BIN_MAX		10++typedef struct {+	char		name[PM_LEN];+	char		help[PM_LEN];+	char		type[PM_LEN];+	char		label[PM_LABEL_MAX][PM_LEN];+	uint32_t	n_label;

is this simply the max labels for a metric?

nicboul

comment created time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

+#include <stdarg.h>+#include <stdint.h>+#include <stdio.h>+#include <string.h>++#define PM_COUNTER	"counter"+#define PM_GAUGE	"gauge"+#define PM_HISTOGRAM	"histogram"++#define PM_LEN			128+#define PM_LABEL_MAX		5+#define PM_LABEL_VAL_MAX	5+#define PM_METRIC_MAX		30+#define PM_HIST_BIN_MAX		10++typedef struct {+	char		name[PM_LEN];+	char		help[PM_LEN];+	char		type[PM_LEN];+	char		label[PM_LABEL_MAX][PM_LEN];+	uint32_t	n_label;+	double		bin[PM_HIST_BIN_MAX];+	uint32_t	n_bin;+	struct {+		char	lblval[PM_LABEL_MAX][PM_LEN];+		union {+			double	 	counter;+			double		gauge;+			struct {+				double		sum;+				uint64_t	cnt[PM_HIST_BIN_MAX];+				uint64_t	inf;+			} histogram;+		};+	} s[PM_LABEL_VAL_MAX];+	uint32_t	n_store;

what exactly is n_store representing?

nicboul

comment created time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

+#include <stdarg.h>+#include <stdint.h>+#include <stdio.h>+#include <string.h>++#define PM_COUNTER	"counter"+#define PM_GAUGE	"gauge"+#define PM_HISTOGRAM	"histogram"++#define PM_LEN			128+#define PM_LABEL_MAX		5+#define PM_LABEL_VAL_MAX	5+#define PM_METRIC_MAX		30+#define PM_HIST_BIN_MAX		10++typedef struct {+	char		name[PM_LEN];+	char		help[PM_LEN];+	char		type[PM_LEN];+	char		label[PM_LABEL_MAX][PM_LEN];+	uint32_t	n_label;+	double		bin[PM_HIST_BIN_MAX];+	uint32_t	n_bin;+	struct {+		char	lblval[PM_LABEL_MAX][PM_LEN];+		union {+			double	 	counter;+			double		gauge;+			struct {+				double		sum;+				uint64_t	cnt[PM_HIST_BIN_MAX];+				uint64_t	inf;+			} histogram;+		};+	} s[PM_LABEL_VAL_MAX];+	uint32_t	n_store;+} pm_metric;++static int		 pm_metric_get_store(pm_metric *m, va_list *);+static pm_metric	 metrics[PM_METRIC_MAX] = {{{0}}};++int+pm_metric_get_store(pm_metric *m, va_list *ap1)+{+	va_list		ap;+	uint32_t	i, j;+	int		idx = -1;+	uint32_t	ret;+	uint8_t		match;+	const char	*label;+	char		lblval[PM_LABEL_MAX][PM_LEN] = {{0}};++	va_copy(ap, *ap1);+	for (i = 0; i < m->n_label; i++) {+		label = va_arg(ap, const char *);++		for (j = 0; j < m->n_label; j++) {+			if (strcmp(label, m->label[j]) == 0)+				break;+		}+		ret = snprintf(lblval[j], sizeof(lblval[j]), "\"%s\"",+			va_arg(ap, const char *));+		if (ret >= sizeof(lblval[j])) goto out;+	}+	va_end(ap);++	match = 0;+	for (i = 0; i < PM_LABEL_VAL_MAX; i++) {+		if (m->s[i].lblval[0][0] == '\0') {+			if (idx == -1)+				idx = i;+			continue;+		}+		for (j = 0; j < m->n_label; j++) {+			if (strcmp(m->s[i].lblval[j], lblval[j]) != 0)+				break;+		}+		if (j == m->n_label) {+			match = 1;+			idx = i;+			break;+		}+	}++	if (match == 0 && idx != -1) {+		for (i = 0; i < m->n_label; i++) {+			snprintf(m->s[idx].lblval[i],+				sizeof(m->s[idx].lblval[i]), "%s", lblval[i]);+			if (ret >= sizeof(lblval[j])) goto out;+		}+		m->n_store++;+	}+out:+	return (idx);+}+++pm_metric *+pm_metric_add(const char *name, const char *help, const char *type, const uint32_t n_label, ...)+{+	pm_metric	*m = NULL;+	va_list		 args;+	uint32_t	 i, j;+	uint32_t	 ret = 0;++	for (i = 0; i < PM_METRIC_MAX; i++)+		if (metrics[i].name[0] == '\0')+			break;++	if (i >= PM_METRIC_MAX)+		goto out;++	va_start(args, n_label);+	for (j = 0; j < n_label && j < PM_LABEL_MAX; j++) {+		ret = snprintf(metrics[i].label[j], sizeof(metrics[i].label[j]),+			"%s", va_arg(args, const char *));+		if (ret >= sizeof(metrics[i].label[j])) goto out;

what exactly is this conditional checking for? i.e. if the label value overflowed the max allowable PM_LEN of 128?

nicboul

comment created time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

+#include <stdarg.h>+#include <stdint.h>+#include <stdio.h>+#include <string.h>++#define PM_COUNTER	"counter"+#define PM_GAUGE	"gauge"+#define PM_HISTOGRAM	"histogram"++#define PM_LEN			128+#define PM_LABEL_MAX		5+#define PM_LABEL_VAL_MAX	5+#define PM_METRIC_MAX		30+#define PM_HIST_BIN_MAX		10++typedef struct {+	char		name[PM_LEN];+	char		help[PM_LEN];+	char		type[PM_LEN];+	char		label[PM_LABEL_MAX][PM_LEN];+	uint32_t	n_label;+	double		bin[PM_HIST_BIN_MAX];+	uint32_t	n_bin;+	struct {+		char	lblval[PM_LABEL_MAX][PM_LEN];+		union {+			double	 	counter;+			double		gauge;+			struct {+				double		sum;+				uint64_t	cnt[PM_HIST_BIN_MAX];+				uint64_t	inf;+			} histogram;+		};+	} s[PM_LABEL_VAL_MAX];+	uint32_t	n_store;+} pm_metric;++static int		 pm_metric_get_store(pm_metric *m, va_list *);+static pm_metric	 metrics[PM_METRIC_MAX] = {{{0}}};++int+pm_metric_get_store(pm_metric *m, va_list *ap1)+{+	va_list		ap;+	uint32_t	i, j;+	int		idx = -1;+	uint32_t	ret;+	uint8_t		match;+	const char	*label;+	char		lblval[PM_LABEL_MAX][PM_LEN] = {{0}};++	va_copy(ap, *ap1);+	for (i = 0; i < m->n_label; i++) {+		label = va_arg(ap, const char *);++		for (j = 0; j < m->n_label; j++) {+			if (strcmp(label, m->label[j]) == 0)+				break;+		}+		ret = snprintf(lblval[j], sizeof(lblval[j]), "\"%s\"",+			va_arg(ap, const char *));+		if (ret >= sizeof(lblval[j])) goto out;+	}+	va_end(ap);++	match = 0;+	for (i = 0; i < PM_LABEL_VAL_MAX; i++) {+		if (m->s[i].lblval[0][0] == '\0') {+			if (idx == -1)+				idx = i;+			continue;+		}+		for (j = 0; j < m->n_label; j++) {+			if (strcmp(m->s[i].lblval[j], lblval[j]) != 0)+				break;+		}+		if (j == m->n_label) {+			match = 1;+			idx = i;+			break;+		}+	}++	if (match == 0 && idx != -1) {+		for (i = 0; i < m->n_label; i++) {+			snprintf(m->s[idx].lblval[i],+				sizeof(m->s[idx].lblval[i]), "%s", lblval[i]);+			if (ret >= sizeof(lblval[j])) goto out;+		}+		m->n_store++;+	}+out:+	return (idx);+}+++pm_metric *+pm_metric_add(const char *name, const char *help, const char *type, const uint32_t n_label, ...)+{+	pm_metric	*m = NULL;+	va_list		 args;+	uint32_t	 i, j;+	uint32_t	 ret = 0;++	for (i = 0; i < PM_METRIC_MAX; i++)+		if (metrics[i].name[0] == '\0')+			break;++	if (i >= PM_METRIC_MAX)+		goto out;++	va_start(args, n_label);+	for (j = 0; j < n_label && j < PM_LABEL_MAX; j++) {+		ret = snprintf(metrics[i].label[j], sizeof(metrics[i].label[j]),+			"%s", va_arg(args, const char *));+		if (ret >= sizeof(metrics[i].label[j])) goto out;+	}+	va_end(args);++	ret = snprintf(metrics[i].help, sizeof(metrics[i].help), "%s", help);+	if (ret >= sizeof(metrics[i].help)) goto out;++	ret = snprintf(metrics[i].type, sizeof(metrics[i].type), "%s", type);+	if (ret > sizeof(metrics[i].type)) goto out;++	ret = snprintf(metrics[i].name, sizeof(metrics[i].name), "%s", name);+	if (ret > sizeof(metrics[i].name)) {+		metrics[i].name[0] = '\0';

Could this default zero value string be defined above as a variable and reference instead of hardcoded like this? I see that it's also checked on line 69. Might just help a bit towards readability.

nicboul

comment created time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

+#include <stdarg.h>+#include <stdint.h>+#include <stdio.h>+#include <string.h>++#define PM_COUNTER	"counter"+#define PM_GAUGE	"gauge"+#define PM_HISTOGRAM	"histogram"++#define PM_LEN			128+#define PM_LABEL_MAX		5+#define PM_LABEL_VAL_MAX	5+#define PM_METRIC_MAX		30+#define PM_HIST_BIN_MAX		10++typedef struct {+	char		name[PM_LEN];+	char		help[PM_LEN];+	char		type[PM_LEN];+	char		label[PM_LABEL_MAX][PM_LEN];+	uint32_t	n_label;+	double		bin[PM_HIST_BIN_MAX];+	uint32_t	n_bin;+	struct {+		char	lblval[PM_LABEL_MAX][PM_LEN];+		union {+			double	 	counter;+			double		gauge;+			struct {+				double		sum;+				uint64_t	cnt[PM_HIST_BIN_MAX];+				uint64_t	inf;+			} histogram;+		};+	} s[PM_LABEL_VAL_MAX];+	uint32_t	n_store;+} pm_metric;++static int		 pm_metric_get_store(pm_metric *m, va_list *);+static pm_metric	 metrics[PM_METRIC_MAX] = {{{0}}};++int

Would you also mind adding a comment at the top of each function just indicating what it does?

nicboul

comment created time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

+#include <stdarg.h>+#include <stdint.h>+#include <stdio.h>+#include <string.h>++#define PM_COUNTER	"counter"+#define PM_GAUGE	"gauge"+#define PM_HISTOGRAM	"histogram"++#define PM_LEN			128+#define PM_LABEL_MAX		5+#define PM_LABEL_VAL_MAX	5+#define PM_METRIC_MAX		30+#define PM_HIST_BIN_MAX		10++typedef struct {+	char		name[PM_LEN];+	char		help[PM_LEN];+	char		type[PM_LEN];+	char		label[PM_LABEL_MAX][PM_LEN];+	uint32_t	n_label;+	double		bin[PM_HIST_BIN_MAX];+	uint32_t	n_bin;+	struct {+		char	lblval[PM_LABEL_MAX][PM_LEN];+		union {+			double	 	counter;+			double		gauge;+			struct {+				double		sum;+				uint64_t	cnt[PM_HIST_BIN_MAX];+				uint64_t	inf;+			} histogram;+		};+	} s[PM_LABEL_VAL_MAX];+	uint32_t	n_store;+} pm_metric;++static int		 pm_metric_get_store(pm_metric *m, va_list *);+static pm_metric	 metrics[PM_METRIC_MAX] = {{{0}}};++int+pm_metric_get_store(pm_metric *m, va_list *ap1)

This function is a little hard to read - mind adding some comments here to help the reader understand what is happening?

nicboul

comment created time in 2 months

Pull request review commentnetvfy/libnv

add prometheus exporter

+#include <stdarg.h>+#include <stdint.h>+#include <stdio.h>+#include <string.h>++#define PM_COUNTER	"counter"+#define PM_GAUGE	"gauge"+#define PM_HISTOGRAM	"histogram"++#define PM_LEN			128

nit: huh is there some weird spacing here and below? with these const values - seems like a difference in # tabs or spaces?

nicboul

comment created time in 2 months

more