diff --git a/clients/shmem/villas-shmem.cpp b/clients/shmem/villas-shmem.cpp index 8970cd36e..60e78a189 100644 --- a/clients/shmem/villas-shmem.cpp +++ b/clients/shmem/villas-shmem.cpp @@ -102,7 +102,7 @@ protected: avail = shmem_int_alloc(&shm, outsmps, readcnt); if (avail < readcnt) - logger->warn("Pool underrun: %d / %d\n", avail, readcnt); + logger->warn("Pool underrun: {} / {}", avail, readcnt); for (int i = 0; i < avail; i++) { outsmps[i]->sequence = insmps[i]->sequence; diff --git a/common b/common index fdf5e6371..dba712a0e 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit fdf5e6371606f247d5adb17caa701b19f9113ec5 +Subproject commit dba712a0e7b2f38fb3a435f0c74c56cbc0024e48 diff --git a/etc/Shmem_mqtt.conf b/etc/Shmem_mqtt.conf new file mode 100644 index 000000000..859ff026e --- /dev/null +++ b/etc/Shmem_mqtt.conf @@ -0,0 +1,78 @@ +nodes = { + sig = { + + type = "signal1" + + signal = "sine" + } + + + dpsim = { + enabled = false, + type = "shmem", + in = { + name = "/dpsim-villas", # Name of shared memory segment for sending side + hooks = ( + { type = "stats" } + ), + signals = { + # count = 2, + # type = "float" + count = 1, + type = "complex" + } + }, + out = { + name = "/villas-dpsim" # Name of shared memory segment for receiving side + signals = { + count = 1, + type = "complex" + } + + }, + queuelen = 1024, # Length of the queues + polling = true, # We can busy-wait or use pthread condition variables for synchronizations + }, + + broker = { + type = "mqtt", + format = "json", + #host = "localhost", + host = "137.226.133.157" + port = 1883, + retain = false, + + out = { + publish = "dpsim->dist" + } + + in = { + subscribe = "dist->dpsim", + + signals = { + count = 1, + type = "complex" + } + } + } +} + +paths = ( + { + enabled = false + in = "sig", + out = "broker", + + # mode: any/all + # Condition of which/how many source nodes have to receive + # at least one sample for the path to be triggered + mode = "any", +# reverse = true + } + # ,{ + # in = "nano"; + # out = "dpsim"; + # mode = "any" + # } + +) diff --git a/etc/demo.json b/etc/demo.json new file mode 100644 index 000000000..f6fd8d62b --- /dev/null +++ b/etc/demo.json @@ -0,0 +1,37 @@ +{ + "hugepages": 0, + "http": { + "htdocs": "/usr/share/villas/node/web" + }, + "nodes": { + "sig": { + "type": "signal", + "signal": "mixed", + "values": 5, + "rate": 20 + }, + "ws_sig": { + "type": "websocket" + }, + "ws_lo": { + "type": "websocket" + }, + "lo": { + "type": "loopback" + } + }, + "paths": [ + { + "in": "sig", + "out": "ws_sig" + }, + { + "in": "ws_lo", + "out": "lo" + }, + { + "in": "lo", + "out": "ws_lo" + } + ] +} diff --git a/etc/examples/nodes/advio.conf b/etc/examples/nodes/advio.conf deleted file mode 100644 index 65fe83116..000000000 --- a/etc/examples/nodes/advio.conf +++ /dev/null @@ -1,43 +0,0 @@ -/** Test advanced file IO using libcurl. - * - * The syntax of this file is similar to JSON. - * A detailed description of the format can be found here: - * http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files - * - * @author Steffen Vogel - * @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASnode - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *********************************************************************************/ - -nodes = { - remote_file = { - type = "file", - - uri = "https://Q9ZHPBD5eRlZcAi:badpass@rwth-aachen.sciebo.de/public.php/webdav/data/demo_in.dat", - - # The output path accepts all format tokens of (see strftime(3)) - #uri = "https://Q9ZHPBD5eRlZcAi:badpass@rwth-aachen.sciebo.de/public.php/webdav/data/demo_%y-%m-%d_%H-%M-%S.dat", - - out = { - mode = "a+" # You might want to use "a+" to append to a file - } - in = { - rate = 1 - } - } -} diff --git a/etc/examples/nodes/fpga.conf b/etc/examples/nodes/fpga.conf new file mode 100644 index 000000000..3551d5e2a --- /dev/null +++ b/etc/examples/nodes/fpga.conf @@ -0,0 +1,33 @@ +logging = { + level = "debug" +} + +fpgas = { + vc707 = { + id = "10ee:7022" + do_reset = true + + ips = "@include ../etc/examples/nodes/vc707_ips.conf" + } +} + +nodes = { + dma_0 = { + type = "fpga", + + card = "vc707" + datamover = "dma_0" + use_irqs = false + } +} + +paths = ( + { + in = "dma_0" + out = [ ] + + hooks = ( + { type = "print" } + ) + } +) diff --git a/etc/examples/nodes/vc707_ips.conf b/etc/examples/nodes/vc707_ips.conf new file mode 100644 index 000000000..fef945750 --- /dev/null +++ b/etc/examples/nodes/vc707_ips.conf @@ -0,0 +1,253 @@ +{ + "timer_0_axi_timer_0": { + "vlnv": "xilinx.com:ip:axi_timer:2.0", + "irqs": { + "generateout0": "pcie_0_axi_pcie_intc_0:0" + } + }, + "hier_0_axis_data_fifo_1": { + "ports": [ + { + "role": "master", + "name": "AXIS", + "target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S04_AXIS" + }, + { + "role": "slave", + "name": "AXIS", + "target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M04_AXIS" + } + ], + "vlnv": "xilinx.com:ip:axis_data_fifo:2.0" + }, + "hier_0_axis_interconnect_0_axis_interconnect_0_xbar": { + "ports": [ + { + "role": "slave", + "name": "S00_AXIS", + "target": "hier_0_aurora_axis_0:m_axis" + }, + { + "role": "master", + "name": "M00_AXIS", + "target": "hier_0_aurora_axis_0:s_axis" + }, + { + "role": "slave", + "name": "S01_AXIS", + "target": "hier_0_axi_dma_axi_dma_0:MM2S" + }, + { + "role": "master", + "name": "M01_AXIS", + "target": "hier_0_axi_dma_axi_dma_0:S2MM" + }, + { + "role": "slave", + "name": "S02_AXIS", + "target": "hier_0_axi_fifo_mm_s_0:STR_TXD" + }, + { + "role": "master", + "name": "M02_AXIS", + "target": "hier_0_axi_fifo_mm_s_0:STR_RXD" + }, + { + "role": "slave", + "name": "S03_AXIS", + "target": "hier_0_axis_data_fifo_0:AXIS" + }, + { + "role": "master", + "name": "M03_AXIS", + "target": "hier_0_axis_data_fifo_0:AXIS" + }, + { + "role": "slave", + "name": "S04_AXIS", + "target": "hier_0_axis_data_fifo_1:AXIS" + }, + { + "role": "master", + "name": "M04_AXIS", + "target": "hier_0_axis_data_fifo_1:AXIS" + } + ], + "num_ports": 5, + "vlnv": "xilinx.com:ip:axis_switch:1.1" + }, + "hier_0_axis_data_fifo_0": { + "ports": [ + { + "role": "master", + "name": "AXIS", + "target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S03_AXIS" + }, + { + "role": "slave", + "name": "AXIS", + "target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M03_AXIS" + } + ], + "vlnv": "xilinx.com:ip:axis_data_fifo:2.0" + }, + "hier_0_aurora_axis_0": { + "ports": [ + { + "role": "master", + "name": "m_axis", + "target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S00_AXIS" + }, + { + "role": "slave", + "name": "s_axis", + "target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M00_AXIS" + } + ], + "vlnv": "acs.eonerc.rwth-aachen.de:user:aurora_axis:1.16" + }, + "pcie_0_axi_reset_0": { + "vlnv": "xilinx.com:ip:axi_gpio:2.0" + }, + "hier_0_axi_fifo_mm_s_0": { + "ports": [ + { + "role": "master", + "name": "STR_TXD", + "target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S02_AXIS" + }, + { + "role": "slave", + "name": "STR_RXD", + "target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M02_AXIS" + } + ], + "vlnv": "xilinx.com:ip:axi_fifo_mm_s:4.2", + "irqs": { + "interrupt": "pcie_0_axi_pcie_intc_0:1" + } + }, + "hier_0_axi_dma_axi_dma_0": { + "ports": [ + { + "role": "master", + "name": "MM2S", + "target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S01_AXIS" + }, + { + "role": "slave", + "name": "S2MM", + "target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M01_AXIS" + } + ], + "vlnv": "xilinx.com:ip:axi_dma:7.1", + "memory-view": { + "M_AXI_MM2S": { + "pcie_0_axi_pcie_0": { + "BAR0": { + "highaddr": 4294967295, + "size": 4294967296, + "baseaddr": 0 + } + } + }, + "M_AXI_S2MM": { + "pcie_0_axi_pcie_0": { + "BAR0": { + "highaddr": 4294967295, + "size": 4294967296, + "baseaddr": 0 + } + } + } + }, + "irqs": { + "s2mm_introut": "pcie_0_axi_pcie_intc_0:3", + "mm2s_introut": "pcie_0_axi_pcie_intc_0:2" + } + }, + "pcie_0_axi_pcie_intc_0": { + "vlnv": "acs.eonerc.rwth-aachen.de:user:axi_pcie_intc:1.4" + }, + "pcie_0_axi_pcie_0": { + "vlnv": "xilinx.com:ip:axi_pcie:2.9", + "memory-view": { + "M_AXI": { + "timer_0_axi_timer_0": { + "Reg": { + "highaddr": 20479, + "size": 4096, + "baseaddr": 16384 + } + }, + "hier_0_axi_fifo_mm_s_0": { + "Mem0": { + "highaddr": 40959, + "size": 8192, + "baseaddr": 32768 + }, + "Mem1": { + "highaddr": 57343, + "size": 8192, + "baseaddr": 49152 + } + }, + "pcie_0_axi_pcie_0": { + "CTL0": { + "highaddr": 536870911, + "size": 268435456, + "baseaddr": 268435456 + } + }, + "hier_0_aurora_axis_0": { + "reg0": { + "highaddr": 12287, + "size": 4096, + "baseaddr": 8192 + } + }, + "pcie_0_axi_reset_0": { + "Reg": { + "highaddr": 32767, + "size": 4096, + "baseaddr": 28672 + } + }, + "hier_0_axis_interconnect_0_axis_interconnect_0_xbar": { + "Reg": { + "highaddr": 24575, + "size": 4096, + "baseaddr": 20480 + } + }, + "hier_0_axi_dma_axi_dma_0": { + "Reg": { + "highaddr": 16383, + "size": 4096, + "baseaddr": 12288 + } + }, + "pcie_0_axi_pcie_intc_0": { + "reg0": { + "highaddr": 8191, + "size": 4096, + "baseaddr": 4096 + } + } + } + }, + "pcie_bars": { + "BAR0": { + "translation": 0 + } + }, + "axi_bars": { + "BAR0": { + "highaddr": 4294967295, + "size": 4294967296, + "translation": 0, + "baseaddr": 0 + } + } + } +} diff --git a/etc/labs/lab17.conf b/etc/labs/lab17.conf new file mode 100644 index 000000000..e7c143fdb --- /dev/null +++ b/etc/labs/lab17.conf @@ -0,0 +1,138 @@ + +nodes = { + rtds_ss1 = { + type = "socket", + layer = "udp", + format = "gtnet.fake" + + in = { # Local address, i.e. address of villas instance + address = "134.130.169.31:12000" + + signals = ( + { name="trigger", type="integer" }, + { name="if1_tx_phA_dp0_mag", type="float" }, + { name="if1_tx_phA_dp0_phase", type="float" }, + { name="if1_tx_phA_dp1_mag", type="float" }, + { name="if1_tx_phA_dp1_phase", type="float" }, + { name="if1_tx_phA_dp2_mag", type="float" }, + { name="if1_tx_phA_dp2_phase", type="float" }, + { name="if1_tx_phA_dp3_mag", type="float" }, + { name="if1_tx_phA_dp3_phase", type="float" }, + { name="if1_tx_phB_dp0_mag", type="float" }, + { name="if1_tx_phB_dp0_phase", type="float" }, + { name="if1_tx_phB_dp1_mag", type="float" }, + { name="if1_tx_phB_dp1_phase", type="float" }, + { name="if1_tx_phB_dp2_mag", type="float" }, + { name="if1_tx_phB_dp2_phase", type="float" }, + { name="if1_tx_phB_dp3_mag", type="float" }, + { name="if1_tx_phB_dp3_phase", type="float" }, + { name="if1_tx_phC_dp0_mag", type="float" }, + { name="if1_tx_phC_dp0_phase", type="float" }, + { name="if1_tx_phC_dp1_mag", type="float" }, + { name="if1_tx_phC_dp1_phase", type="float" }, + { name="if1_tx_phC_dp2_mag", type="float" }, + { name="if1_tx_phC_dp2_phase", type="float" }, + { name="if1_tx_phC_dp3_mag", type="float" }, + { name="if1_tx_phC_dp3_phase", type="float" } + ) + } + + out = { # Remote address, i.e. address of GTNET card + address = "134.130.169.97:12000" # GTNET#4 -> Rack5(GPC4) + } + } + + rtds_ss2 = { + type = "socket", + layer = "udp", + format = "gtnet.fake" + + in = { + # Local address, i.e. address of villas instance + address = "134.130.169.31:12001" + + signals = ( + { name="trigger", type="integer" }, + { name="if1_tx_phA_dp0_mag", type="float" }, + { name="if1_tx_phA_dp0_phase", type="float" }, + { name="if1_tx_phA_dp1_mag", type="float" }, + { name="if1_tx_phA_dp1_phase", type="float" }, + { name="if1_tx_phA_dp2_mag", type="float" }, + { name="if1_tx_phA_dp2_phase", type="float" }, + { name="if1_tx_phA_dp3_mag", type="float" }, + { name="if1_tx_phA_dp3_phase", type="float" }, + { name="if1_tx_phB_dp0_mag", type="float" }, + { name="if1_tx_phB_dp0_phase", type="float" }, + { name="if1_tx_phB_dp1_mag", type="float" }, + { name="if1_tx_phB_dp1_phase", type="float" }, + { name="if1_tx_phB_dp2_mag", type="float" }, + { name="if1_tx_phB_dp2_phase", type="float" }, + { name="if1_tx_phB_dp3_mag", type="float" }, + { name="if1_tx_phB_dp3_phase", type="float" }, + { name="if1_tx_phC_dp0_mag", type="float" }, + { name="if1_tx_phC_dp0_phase", type="float" }, + { name="if1_tx_phC_dp1_mag", type="float" }, + { name="if1_tx_phC_dp1_phase", type="float" }, + { name="if1_tx_phC_dp2_mag", type="float" }, + { name="if1_tx_phC_dp2_phase", type="float" }, + { name="if1_tx_phC_dp3_mag", type="float" }, + { name="if1_tx_phC_dp3_phase", type="float" } + ) + + } + + out = { + # Remote address, i.e. address of GTNET card + address = "134.130.169.98:12000" # GTNET#5 -> Rack1(GPC4) + } + } + + rtds_ss1_monitoring = { + type = "socket" + layer = "udp" + format = "gtnet.fake" + + in = { # Local address, i.e. address of villas instance + address = "134.130.169.31:12002" + + signals = ( + { name="orgn_V3phRMSintrf", type="float", unit="V" }, + { name="orgn_Pintrf", type="float", unit="W" }, + { name="orgn_Qintrf", type="float", unit="Var" }, + { name="orgn_Sintrf", type="float", unit="VA" }, + { name="if1_V3phRMS", type="float", unit="V" }, + { name="if1_I3phRMS", type="float", unit="A" }, + { name="if1_P", type="float", unit="W" }, + { name="if1_Q", type="float", unit="Var" }, + { name="if1_S", type="float", unit="VA" } + ) + } + + out = { # Remote address, i.e. address of GTNET card + address = "134.130.169.97:12000" + } + } + + + web_monitoring = { + type = "websocket" + + destinations = [ + "https://villas-new.k8s.eonerc.rwth-aachen.de//ws/relay/lab17" + ] + } +} + +paths = ( + { + in = "rtds_ss1", + out = "rtds_ss2", + reverse = true + }, + { + enabled = false, + in = "rtds_ss1_monitoring", + out = "web_monitoring", + reverse = true + } +) diff --git a/include/villas/api/session.hpp b/include/villas/api/session.hpp index 489913f06..1e34f4720 100644 --- a/include/villas/api/session.hpp +++ b/include/villas/api/session.hpp @@ -43,6 +43,7 @@ namespace api { class Request; class Response; class StatusRequest; +class RequestFactory; /** A connection via HTTP REST or WebSockets to issue API requests. */ class Session { @@ -50,7 +51,7 @@ class Session { public: friend Request; /**< Requires access to wsi for getting URL args and headers */ friend StatusRequest; /**< Requires access to wsi for context status */ - + friend RequestFactory; enum State { ESTABLISHED, diff --git a/include/villas/config.hpp b/include/villas/config.hpp index be01a0bc3..f5253e6be 100644 --- a/include/villas/config.hpp +++ b/include/villas/config.hpp @@ -33,7 +33,6 @@ #include #include -#include namespace villas { namespace node { @@ -65,9 +64,6 @@ protected: /** Load configuration from local file. */ FILE * loadFromLocalFile(const std::string &u); - /** Load configuration from a remote URI via advio. */ - AFILE * loadFromRemoteFile(const std::string &u); - /** Resolve custom include directives. */ json_t * resolveIncludes(json_t *in); diff --git a/include/villas/config_helper.hpp b/include/villas/config_helper.hpp index e70dc5aff..3cc784be3 100644 --- a/include/villas/config_helper.hpp +++ b/include/villas/config_helper.hpp @@ -31,7 +31,7 @@ #include /** Convert a libconfig object to a jansson object */ -json_t *config_to_json(config_setting_t *cfg); +json_t *config_to_json(config_setting_t *json); /** Convert a jansson object into a libconfig object. */ int json_to_config(json_t *json, config_setting_t *parent); diff --git a/include/villas/dumper.hpp b/include/villas/dumper.hpp index 560f4e509..81f891ad3 100644 --- a/include/villas/dumper.hpp +++ b/include/villas/dumper.hpp @@ -23,6 +23,8 @@ #pragma once +#include + #include namespace villas { @@ -35,6 +37,7 @@ protected: std::string socketName; bool supressRepeatedWarning; uint64_t warningCounter; + Logger logger; public: Dumper(const std::string &socketNameIn); diff --git a/include/villas/hook.hpp b/include/villas/hook.hpp index 4ccbac94a..3b2a4c1a4 100644 --- a/include/villas/hook.hpp +++ b/include/villas/hook.hpp @@ -72,7 +72,7 @@ protected: struct vlist signals; - json_t *cfg; /**< A JSON object containing the configuration of the hook. */ + json_t *config; /**< A JSON object containing the configuration of the hook. */ public: Hook(struct vpath *p, struct vnode *n, int fl, int prio, bool en = true); @@ -142,7 +142,7 @@ public: json_t * getConfig() const { - return cfg; + return config; } bool isEnabled() const diff --git a/include/villas/hook_list.hpp b/include/villas/hook_list.hpp index abd61747d..0cc2756cb 100644 --- a/include/villas/hook_list.hpp +++ b/include/villas/hook_list.hpp @@ -57,7 +57,7 @@ int hook_list_destroy(struct vlist *hs) __attribute__ ((warn_unused_result)); * hooks = [ "print" ] * } */ -void hook_list_parse(struct vlist *hs, json_t *cfg, int mask, struct vpath *p, struct vnode *n); +void hook_list_parse(struct vlist *hs, json_t *json, int mask, struct vpath *p, struct vnode *n); void hook_list_prepare(struct vlist *hs, struct vlist *sigs, int mask, struct vpath *p, struct vnode *n); @@ -75,4 +75,4 @@ void hook_list_stop(struct vlist *hs); struct vlist * hook_list_get_signals(struct vlist *hs); -json_t * hook_list_to_json(struct vlist *hs); \ No newline at end of file +json_t * hook_list_to_json(struct vlist *hs); diff --git a/include/villas/hooks/decimate.hpp b/include/villas/hooks/decimate.hpp index a00e8a911..26f617ce2 100644 --- a/include/villas/hooks/decimate.hpp +++ b/include/villas/hooks/decimate.hpp @@ -58,7 +58,7 @@ public: virtual void start(); - virtual void parse(json_t *cfg); + virtual void parse(json_t *json); virtual Hook::Reason process(sample *smp); }; diff --git a/include/villas/hooks/limit_rate.hpp b/include/villas/hooks/limit_rate.hpp index db5aa8b0f..0be8b3391 100644 --- a/include/villas/hooks/limit_rate.hpp +++ b/include/villas/hooks/limit_rate.hpp @@ -56,7 +56,7 @@ public: deadtime = 1.0 / rate; } - virtual void parse(json_t *cfg); + virtual void parse(json_t *json); virtual Hook::Reason process(sample *smp); }; diff --git a/include/villas/io.h b/include/villas/io.h index 4ea65a5a9..9bf9530bc 100644 --- a/include/villas/io.h +++ b/include/villas/io.h @@ -23,7 +23,6 @@ #pragma once -#include #include #include #include @@ -43,7 +42,6 @@ enum class IOFlags { enum class IOMode { STDIO, - ADVIO, CUSTOM }; @@ -58,10 +56,7 @@ struct io { * format::{open,close,eof,rewind} functions and the private * data in io::_vd. */ - union { - FILE *std; - AFILE *adv; - } stream; + FILE *stream; char *buffer; size_t buflen; diff --git a/include/villas/kernel/tc_netem.hpp b/include/villas/kernel/tc_netem.hpp index 931501c05..893fe9edb 100644 --- a/include/villas/kernel/tc_netem.hpp +++ b/include/villas/kernel/tc_netem.hpp @@ -51,12 +51,12 @@ typedef uint32_t tc_hdl_t; /** Parse network emulator (netem) settings. * - * @param cfg A jansson object containing the settings. + * @param json A jansson object containing the settings. * @param[out] ne A pointer to a libnl3 qdisc object where setting will be written to. * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ -int netem_parse(struct rtnl_qdisc **ne, json_t *cfg); +int netem_parse(struct rtnl_qdisc **ne, json_t *json); /** Print network emulator (netem) setting into buffer. * diff --git a/include/villas/mapping.h b/include/villas/mapping.h index 8ef2d46f9..5e7973085 100644 --- a/include/villas/mapping.h +++ b/include/villas/mapping.h @@ -107,13 +107,13 @@ int mapping_entry_init(struct mapping_entry *me); int mapping_entry_destroy(struct mapping_entry *me); -int mapping_entry_parse(struct mapping_entry *me, json_t *cfg); +int mapping_entry_parse(struct mapping_entry *me, json_t *json); int mapping_entry_parse_str(struct mapping_entry *e, const std::string &str); int mapping_entry_to_str(const struct mapping_entry *me, unsigned index, char **str); -int mapping_list_parse(struct vlist *ml, json_t *cfg); +int mapping_list_parse(struct vlist *ml, json_t *json); int mapping_list_prepare(struct vlist *ml, struct vlist *nodes); diff --git a/include/villas/node.h b/include/villas/node.h index 9f7e94f08..aff09fff4 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -40,6 +40,7 @@ #include #include #include +#include #if defined(LIBNL3_ROUTE_FOUND) && defined(__linux__) #define WITH_NETEM @@ -63,6 +64,7 @@ struct vnode { bool enabled; enum State state; + villas::Logger logger; char *_name; /**< Singleton: A string used to print to screen. */ char *_name_long; /**< Singleton: A string used to print to screen. */ @@ -97,7 +99,7 @@ struct vnode { struct vnode_type *_vt; /**< Virtual functions (C++ OOP style) */ void *_vd; /**< Virtual data (used by struct vnode::_vt functions) */ - json_t *cfg; /**< A JSON object containing the configuration of the node. */ + json_t *config; /**< A JSON object containing the configuration of the node. */ }; /** Initialize node with default values */ @@ -108,11 +110,11 @@ int node_prepare(struct vnode *n); /** Parse settings of a node. * - * @param cfg A JSON object containing the configuration of the node. + * @param json A JSON object containing the configuration of the node. * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ -int node_parse(struct vnode *n, json_t *cfg, const uuid_t sn_uuid); +int node_parse(struct vnode *n, json_t *json, const uuid_t sn_uuid); /** Parse an array or single node and checks if they exist in the "nodes" section. * @@ -120,14 +122,14 @@ int node_parse(struct vnode *n, json_t *cfg, const uuid_t sn_uuid); * out = [ "sintef", "scedu" ] * out = "acs" * - * @param cfg A JSON array or string. See examples above. + * @param json A JSON array or string. See examples above. * @param nodes The nodes will be added to this list. * @param all This list contains all valid nodes. */ -int node_list_parse(struct vlist *list, json_t *cfg, struct vlist *all); +int node_list_parse(struct vlist *list, json_t *json, struct vlist *all); /** Parse the list of signal definitions. */ -int node_parse_signals(struct vlist *list, json_t *cfg); +int node_parse_signals(struct vlist *list, json_t *json); /** Validate node configuration. */ int node_check(struct vnode *n); diff --git a/include/villas/node_direction.h b/include/villas/node_direction.h index fe051ecd5..ba6df1720 100644 --- a/include/villas/node_direction.h +++ b/include/villas/node_direction.h @@ -37,8 +37,8 @@ struct vnode; enum class NodeDir { - IN, /**< VILLASnode is receiving/reading */ - OUT /**< VILLASnode is sending/writing */ + IN, /**< VILLASnode is receiving/reading */ + OUT /**< VILLASnode is sending/writing */ }; struct vnode_direction { @@ -47,19 +47,19 @@ struct vnode_direction { int enabled; int builtin; /**< This node should use built-in hooks by default. */ - unsigned vectorize; /**< Number of messages to send / recv at once (scatter / gather) */ + unsigned vectorize; /**< Number of messages to send / recv at once (scatter / gather) */ struct vlist hooks; /**< List of read / write hooks (struct hook). */ struct vlist signals; /**< Signal description. */ - json_t *cfg; /**< A JSON object containing the configuration of the node. */ + json_t *config; /**< A JSON object containing the configuration of the node. */ }; int node_direction_init(struct vnode_direction *nd, enum NodeDir dir, struct vnode *n) __attribute__ ((warn_unused_result)); int node_direction_destroy(struct vnode_direction *nd, struct vnode *n) __attribute__ ((warn_unused_result)); -int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *cfg); +int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *json); int node_direction_check(struct vnode_direction *nd, struct vnode *n); diff --git a/include/villas/node_type.h b/include/villas/node_type.h index ef9c77335..331eb8858 100644 --- a/include/villas/node_type.h +++ b/include/villas/node_type.h @@ -31,6 +31,7 @@ #include #include #include +#include /* Forward declarations */ struct vnode; @@ -103,11 +104,11 @@ struct vnode_type { * This callback is optional. It will only be called if non-null. * * @param n A pointer to the node object. - * @param cfg A JSON object containing the configuration of the node. + * @param json A JSON object containing the configuration of the node. * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ - int (*parse)(struct vnode *n, json_t *cfg); + int (*parse)(struct vnode *n, json_t *json); /** Check the current node configuration for plausability and errors. * diff --git a/include/villas/nodes/can.hpp b/include/villas/nodes/can.hpp index 34bb1a869..e9499361e 100644 --- a/include/villas/nodes/can.hpp +++ b/include/villas/nodes/can.hpp @@ -64,7 +64,7 @@ int can_init(struct vnode *n); int can_destroy(struct vnode *n); /** @see node_type::parse */ -int can_parse(struct vnode *n, json_t *cfg); +int can_parse(struct vnode *n, json_t *json); /** @see node_type::print */ char * can_print(struct vnode *n); diff --git a/include/villas/nodes/comedi.hpp b/include/villas/nodes/comedi.hpp index 9ba6e399c..61dbf593b 100644 --- a/include/villas/nodes/comedi.hpp +++ b/include/villas/nodes/comedi.hpp @@ -84,7 +84,7 @@ struct comedi { char * comedi_print(struct vnode *n); /** @see node_type::parse */ -int comedi_parse(struct vnode *n, json_t *cfg); +int comedi_parse(struct vnode *n, json_t *json); /** @see node_type::start */ int comedi_start(struct vnode *n); diff --git a/include/villas/nodes/ethercat.hpp b/include/villas/nodes/ethercat.hpp index 8a1e55a84..850a0165c 100644 --- a/include/villas/nodes/ethercat.hpp +++ b/include/villas/nodes/ethercat.hpp @@ -94,7 +94,7 @@ int ethercat_init(struct vnode *n); int ethercat_destroy(struct vnode *n); /** @see node_type::parse */ -int ethercat_parse(struct vnode *n, json_t *cfg); +int ethercat_parse(struct vnode *n, json_t *json); /** @see node_type::check */ int ethercat_check(struct vnode *n); diff --git a/include/villas/nodes/example.hpp b/include/villas/nodes/example.hpp index 074f88129..71cb5f849 100644 --- a/include/villas/nodes/example.hpp +++ b/include/villas/nodes/example.hpp @@ -58,7 +58,7 @@ int example_init(struct vnode *n); int example_destroy(struct vnode *n); /** @see node_type::parse */ -int example_parse(struct vnode *n, json_t *cfg); +int example_parse(struct vnode *n, json_t *json); /** @see node_type::print */ char * example_print(struct vnode *n); diff --git a/include/villas/nodes/exec.hpp b/include/villas/nodes/exec.hpp index 7e6fd9c1b..9d27ef3d3 100644 --- a/include/villas/nodes/exec.hpp +++ b/include/villas/nodes/exec.hpp @@ -57,7 +57,7 @@ struct exec { char * exec_print(struct vnode *n); /** @see node_type::parse */ -int exec_parse(struct vnode *n, json_t *cfg); +int exec_parse(struct vnode *n, json_t *json); /** @see node_type::start */ int exec_open(struct vnode *n); diff --git a/include/villas/nodes/file.hpp b/include/villas/nodes/file.hpp index 65859f4f1..190def488 100644 --- a/include/villas/nodes/file.hpp +++ b/include/villas/nodes/file.hpp @@ -73,7 +73,7 @@ struct file { char * file_print(struct vnode *n); /** @see node_type::parse */ -int file_parse(struct vnode *n, json_t *cfg); +int file_parse(struct vnode *n, json_t *json); /** @see node_type::start */ int file_start(struct vnode *n); diff --git a/include/villas/nodes/fpga.hpp b/include/villas/nodes/fpga.hpp index 0fff41236..e8296a9f0 100644 --- a/include/villas/nodes/fpga.hpp +++ b/include/villas/nodes/fpga.hpp @@ -77,7 +77,7 @@ int fpga_init(struct vnode *n); int fpga_destroy(struct vnode *n); /** @see node_type::parse */ -int fpga_parse(struct vnode *n, json_t *cfg); +int fpga_parse(struct vnode *n, json_t *json); /** @see node_type::print */ char * fpga_print(struct vnode *n); diff --git a/include/villas/nodes/infiniband.hpp b/include/villas/nodes/infiniband.hpp index caed9338b..243a30eb9 100644 --- a/include/villas/nodes/infiniband.hpp +++ b/include/villas/nodes/infiniband.hpp @@ -116,7 +116,7 @@ int ib_reverse(struct vnode *n); char * ib_print(struct vnode *n); /** @see node_type::parse */ -int ib_parse(struct vnode *n, json_t *cfg); +int ib_parse(struct vnode *n, json_t *json); /** @see node_type::start */ int ib_start(struct vnode *n); diff --git a/include/villas/nodes/influxdb.hpp b/include/villas/nodes/influxdb.hpp index 0e443a395..b92f7de59 100644 --- a/include/villas/nodes/influxdb.hpp +++ b/include/villas/nodes/influxdb.hpp @@ -52,7 +52,7 @@ struct influxdb { char * influxdb_print(struct vnode *n); /** @see node_type::parse */ -int influxdb_parse(struct vnode *n, json_t *cfg); +int influxdb_parse(struct vnode *n, json_t *json); /** @see node_type::start */ int influxdb_open(struct vnode *n); diff --git a/include/villas/nodes/loopback.hpp b/include/villas/nodes/loopback.hpp index a7ec662af..602a2f81e 100644 --- a/include/villas/nodes/loopback.hpp +++ b/include/villas/nodes/loopback.hpp @@ -49,7 +49,7 @@ struct loopback { char * loopback_print(struct vnode *n); /** @see node_type::parse */ -int loopback_parse(struct vnode *n, json_t *cfg); +int loopback_parse(struct vnode *n, json_t *json); /** @see node_type::start */ int loopback_open(struct vnode *n); diff --git a/include/villas/nodes/mqtt.hpp b/include/villas/nodes/mqtt.hpp index 7115fc9db..60e15be68 100644 --- a/include/villas/nodes/mqtt.hpp +++ b/include/villas/nodes/mqtt.hpp @@ -76,7 +76,7 @@ char * mqtt_print(struct vnode *n); int mqtt_prepare(struct vnode *n); /** @see node_type::parse */ -int mqtt_parse(struct vnode *n, json_t *cfg); +int mqtt_parse(struct vnode *n, json_t *json); /** @see node_type::start */ int mqtt_start(struct vnode *n); diff --git a/include/villas/nodes/nanomsg.hpp b/include/villas/nodes/nanomsg.hpp index 9e43d0575..3521f7bdf 100644 --- a/include/villas/nodes/nanomsg.hpp +++ b/include/villas/nodes/nanomsg.hpp @@ -53,7 +53,7 @@ struct nanomsg { char * nanomsg_print(struct vnode *n); /** @see node_type::parse */ -int nanomsg_parse(struct vnode *n, json_t *cfg); +int nanomsg_parse(struct vnode *n, json_t *json); /** @see node_type::start */ int nanomsg_start(struct vnode *n); diff --git a/include/villas/nodes/ngsi.hpp b/include/villas/nodes/ngsi.hpp index 1b6020a0d..a90aa218b 100644 --- a/include/villas/nodes/ngsi.hpp +++ b/include/villas/nodes/ngsi.hpp @@ -81,7 +81,7 @@ int ngsi_type_start(villas::node::SuperNode *sn); int ngsi_type_stop(); /** @see node_type::parse */ -int ngsi_parse(struct vnode *n, json_t *cfg); +int ngsi_parse(struct vnode *n, json_t *json); /** @see node_type::print */ char * ngsi_print(struct vnode *n); diff --git a/include/villas/nodes/opal.hpp b/include/villas/nodes/opal.hpp index a5552a0fa..09f80b4d8 100644 --- a/include/villas/nodes/opal.hpp +++ b/include/villas/nodes/opal.hpp @@ -65,7 +65,7 @@ int opal_register_region(int argc, char *argv[]); int opal_type_stop(); /** @see node_type::parse */ -int opal_parse(struct vnode *n, json_t *cfg); +int opal_parse(struct vnode *n, json_t *json); /** @see node_type::print */ char * opal_print(struct vnode *n); diff --git a/include/villas/nodes/rtp.hpp b/include/villas/nodes/rtp.hpp index 85a414075..ce62ca1c4 100644 --- a/include/villas/nodes/rtp.hpp +++ b/include/villas/nodes/rtp.hpp @@ -64,8 +64,6 @@ enum class RTPHookType { struct rtp { struct rtp_sock *rs; /**< RTP socket */ - villas::Logger logger; - struct { struct sa saddr_rtp; /**< Local/Remote address of the RTP socket */ struct sa saddr_rtcp; /**< Local/Remote address of the RTCP socket */ @@ -109,7 +107,7 @@ struct rtp { char * rtp_print(struct vnode *n); /** @see node_type::parse */ -int rtp_parse(struct vnode *n, json_t *cfg); +int rtp_parse(struct vnode *n, json_t *json); /** @see node_type::start */ int rtp_start(struct vnode *n); diff --git a/include/villas/nodes/shmem.hpp b/include/villas/nodes/shmem.hpp index 7332c4dc6..6a1003f03 100644 --- a/include/villas/nodes/shmem.hpp +++ b/include/villas/nodes/shmem.hpp @@ -51,7 +51,7 @@ struct shmem { char * shmem_print(struct vnode *n); /** @see node_type::parse */ -int shmem_parse(struct vnode *n, json_t *cfg); +int shmem_parse(struct vnode *n, json_t *json); /** @see node_type::start */ int shmem_start(struct vnode *n); diff --git a/include/villas/nodes/signal_generator.hpp b/include/villas/nodes/signal_generator.hpp index 4f4f100d1..ce3a7df35 100644 --- a/include/villas/nodes/signal_generator.hpp +++ b/include/villas/nodes/signal_generator.hpp @@ -80,7 +80,7 @@ struct signal_generator { char * signal_generator_print(struct vnode *n); /** @see node_type::parse */ -int signal_generator_parse(struct vnode *n, json_t *cfg); +int signal_generator_parse(struct vnode *n, json_t *json); /** @see node_type::start */ int signal_generator_start(struct vnode *n); diff --git a/include/villas/nodes/socket.hpp b/include/villas/nodes/socket.hpp index 2ddd1d99c..b646f326d 100644 --- a/include/villas/nodes/socket.hpp +++ b/include/villas/nodes/socket.hpp @@ -84,7 +84,7 @@ int socket_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned int socket_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *release); /** @see node_type::parse */ -int socket_parse(struct vnode *n, json_t *cfg); +int socket_parse(struct vnode *n, json_t *json); /** @see node_type::print */ char * socket_print(struct vnode *n); diff --git a/include/villas/nodes/stats.hpp b/include/villas/nodes/stats.hpp index cbf7f877e..7330c7f5a 100644 --- a/include/villas/nodes/stats.hpp +++ b/include/villas/nodes/stats.hpp @@ -59,9 +59,9 @@ int stats_node_type_start(villas::node::SuperNode *sn); char *stats_node_print(struct vnode *n); /** @see node_type::parse */ -int stats_node_parse(struct vnode *n, json_t *cfg); +int stats_node_parse(struct vnode *n, json_t *json); -int stats_node_parse_signal(struct stats_node_signal *s, json_t *cfg); +int stats_node_parse_signal(struct stats_node_signal *s, json_t *json); /** @see node_type::start */ int stats_node_start(struct vnode *n); diff --git a/include/villas/nodes/test_rtt.hpp b/include/villas/nodes/test_rtt.hpp index 590dd83d1..5a78f0d65 100644 --- a/include/villas/nodes/test_rtt.hpp +++ b/include/villas/nodes/test_rtt.hpp @@ -45,6 +45,8 @@ struct test_rtt_case { char *filename; char *filename_formatted; + + struct vnode *node; }; struct test_rtt { @@ -67,7 +69,7 @@ struct test_rtt { char * test_rtt_print(struct vnode *n); /** @see node_type::parse */ -int test_rtt_parse(struct vnode *n, json_t *cfg); +int test_rtt_parse(struct vnode *n, json_t *json); /** @see node_type::start */ int test_rtt_start(struct vnode *n); diff --git a/include/villas/nodes/zeromq.hpp b/include/villas/nodes/zeromq.hpp index 4eba2f4da..a3c06c9e1 100644 --- a/include/villas/nodes/zeromq.hpp +++ b/include/villas/nodes/zeromq.hpp @@ -78,7 +78,7 @@ struct zeromq { char * zeromq_print(struct vnode *n); /** @see node_type::parse */ -int zeromq_parse(struct vnode *n, json_t *cfg); +int zeromq_parse(struct vnode *n, json_t *json); /** @see node_type::type_start */ int zeromq_type_start(villas::node::SuperNode *sn); diff --git a/include/villas/path.h b/include/villas/path.h index 28e24d529..874d50b74 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -90,7 +90,7 @@ struct vpath { char *_name; /**< Singleton: A string which is used to print this path to screen. */ pthread_t tid; /**< The thread id for this path. */ - json_t *cfg; /**< A JSON object containing the configuration of the path. */ + json_t *config; /**< A JSON object containing the configuration of the path. */ villas::Logger logger; @@ -151,13 +151,13 @@ int path_reverse(struct vpath *p, struct vpath *r); /** Parse a single path and add it to the global configuration. * - * @param cfg A JSON object containing the configuration of the path. + * @param json A JSON object containing the configuration of the path. * @param p Pointer to the allocated memory for this path * @param nodes A linked list of all existing nodes * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ -int path_parse(struct vpath *p, json_t *cfg, struct vlist *nodes, const uuid_t sn_uuid); +int path_parse(struct vpath *p, json_t *json, struct vlist *nodes, const uuid_t sn_uuid); void path_parse_mask(struct vpath *p, json_t *json_mask, struct vlist *nodes); diff --git a/include/villas/sample.h b/include/villas/sample.h index a3b610260..596e71261 100644 --- a/include/villas/sample.h +++ b/include/villas/sample.h @@ -30,6 +30,7 @@ #include #include +#include #include /* Forward declarations */ @@ -122,7 +123,7 @@ int sample_decref(struct sample *s); int sample_copy(struct sample *dst, struct sample *src); /** Dump all details about a sample to debug log */ -void sample_dump(struct sample *s); +void sample_dump(villas::Logger logger, struct sample *s); /** Compare two samples */ int sample_cmp(struct sample *a, struct sample *b, double epsilon, int flags); diff --git a/include/villas/signal.h b/include/villas/signal.h index 6f8861676..e3f6e3ba5 100644 --- a/include/villas/signal.h +++ b/include/villas/signal.h @@ -76,7 +76,7 @@ int signal_decref(struct signal *s); struct signal * signal_copy(struct signal *s); /** Parse signal description. */ -int signal_parse(struct signal *s, json_t *cfg); +int signal_parse(struct signal *s, json_t *json); /** Initialize signal from a mapping_entry. */ int signal_init_from_mapping(struct signal *s, const struct mapping_entry *me, unsigned index); diff --git a/include/villas/signal_data.h b/include/villas/signal_data.h index 4217a0369..3c338cb99 100644 --- a/include/villas/signal_data.h +++ b/include/villas/signal_data.h @@ -67,7 +67,7 @@ int signal_data_print_str(const union signal_data *data, enum SignalType type, c int signal_data_parse_str(union signal_data *data, enum SignalType type, const char *ptr, char **end); -int signal_data_parse_json(union signal_data *data, enum SignalType type, json_t *cfg); +int signal_data_parse_json(union signal_data *data, enum SignalType type, json_t *json); json_t * signal_data_to_json(union signal_data *data, enum SignalType type); diff --git a/include/villas/signal_list.h b/include/villas/signal_list.h index 2cce28ec9..1843a0b07 100644 --- a/include/villas/signal_list.h +++ b/include/villas/signal_list.h @@ -25,6 +25,7 @@ #include +#include #include /* Forward declarations */ @@ -36,13 +37,13 @@ int signal_list_destroy(struct vlist *list) __attribute__ ((warn_unused_result)) int signal_list_clear(struct vlist *list); -int signal_list_parse(struct vlist *list, json_t *cfg); +int signal_list_parse(struct vlist *list, json_t *json); int signal_list_generate(struct vlist *list, unsigned len, enum SignalType fmt); int signal_list_generate2(struct vlist *list, const char *dt); -void signal_list_dump(const struct vlist *list, const union signal_data *data = nullptr, unsigned len = 0); +void signal_list_dump(villas::Logger logger, const struct vlist *list, const union signal_data *data = nullptr, unsigned len = 0); int signal_list_copy(struct vlist *dst, const struct vlist *src); diff --git a/include/villas/stats.hpp b/include/villas/stats.hpp index a864a17d4..8270756a9 100644 --- a/include/villas/stats.hpp +++ b/include/villas/stats.hpp @@ -34,6 +34,7 @@ #include #include #include +#include /* Forward declarations */ struct sample; @@ -94,6 +95,8 @@ protected: static void setupTable(); + Logger logger; + public: Stats(int buckets, int warmup); diff --git a/include/villas/super_node.hpp b/include/villas/super_node.hpp index 3ce2c193e..e342075ef 100644 --- a/include/villas/super_node.hpp +++ b/include/villas/super_node.hpp @@ -97,9 +97,9 @@ public: /** Parse super-node configuration. * - * @param cfg A libjansson object which contains the configuration. + * @param json A libjansson object which contains the configuration. */ - void parse(json_t *cfg); + void parse(json_t *json); /** Check validity of super node configuration. */ void check(); @@ -199,6 +199,11 @@ public: return affinity; } + Logger getLogger() + { + return logger; + } + /** Destroy configuration object. */ ~SuperNode(); }; diff --git a/include/villas/web.hpp b/include/villas/web.hpp index 55e3122ad..f78a5b6e2 100644 --- a/include/villas/web.hpp +++ b/include/villas/web.hpp @@ -75,7 +75,7 @@ public: void stop(); /** Parse HTTPd and WebSocket related options */ - int parse(json_t *cfg); + int parse(json_t *json); Api * getApi() { diff --git a/lib/api/request.cpp b/lib/api/request.cpp index b23c6cedd..36f3fb9d5 100644 --- a/lib/api/request.cpp +++ b/lib/api/request.cpp @@ -43,7 +43,7 @@ Request::toString() Request * RequestFactory::create(Session *s, const std::string &uri, Session::Method meth, unsigned long ct) { - info("api: Trying to find request handler for: uri=%s", uri.c_str()); + s->logger->info("Trying to find request handler for: uri={}", uri); for (auto *rf : plugin::Registry::lookup()) { std::smatch mr; diff --git a/lib/api/requests/config.cpp b/lib/api/requests/config.cpp index 2f1ddde36..64948ecb3 100644 --- a/lib/api/requests/config.cpp +++ b/lib/api/requests/config.cpp @@ -36,7 +36,7 @@ public: virtual Response * execute() { - json_t *cfg = session->getSuperNode()->getConfig(); + json_t *json = session->getSuperNode()->getConfig(); if (method != Session::Method::GET) throw InvalidMethod(this); @@ -44,8 +44,8 @@ public: if (body != nullptr) throw BadRequest("Config endpoint does not accept any body data"); - auto *json_config = cfg - ? json_incref(cfg) + auto *json_config = json + ? json_incref(json) : json_object(); return new JsonResponse(session, HTTP_STATUS_OK, json_config); diff --git a/lib/api/requests/node_stats.cpp b/lib/api/requests/node_stats.cpp index 4bbdf1baa..b52c90882 100644 --- a/lib/api/requests/node_stats.cpp +++ b/lib/api/requests/node_stats.cpp @@ -22,7 +22,6 @@ #include -#include #include #include #include diff --git a/lib/api/requests/node_stats_reset.cpp b/lib/api/requests/node_stats_reset.cpp index 2f7bc56ef..284ebee2b 100644 --- a/lib/api/requests/node_stats_reset.cpp +++ b/lib/api/requests/node_stats_reset.cpp @@ -22,7 +22,6 @@ #include -#include #include #include #include diff --git a/lib/api/requests/restart.cpp b/lib/api/requests/restart.cpp index c418985ae..8a139c6dc 100644 --- a/lib/api/requests/restart.cpp +++ b/lib/api/requests/restart.cpp @@ -98,7 +98,7 @@ public: else /* If no config is provided via request, we will use the previous one */ configUri = session->getSuperNode()->getConfigUri(); - logger->info("Restarting to {}", configUri.c_str()); + logger->info("Restarting to {}", configUri); /* Increment API restart counter */ char *scnt = getenv("VILLAS_API_RESTART_COUNT"); diff --git a/lib/config.cpp b/lib/config.cpp index b7c650933..7dd45432f 100644 --- a/lib/config.cpp +++ b/lib/config.cpp @@ -75,23 +75,15 @@ json_t * Config::load(std::FILE *f, bool resolveInc, bool resolveEnvVars) json_t * Config::load(const std::string &u, bool resolveInc, bool resolveEnvVars) { FILE *f; - AFILE *af = nullptr; if (u == "-") f = loadFromStdio(); - else if (isLocalFile(u)) + else f = loadFromLocalFile(u); - else { - af = loadFromRemoteFile(u); - f = af->file; - } json_t *root = load(f, resolveInc, resolveEnvVars); - if (af) - afclose(af); - else - fclose(f); + fclose(f); return root; } @@ -114,17 +106,6 @@ FILE * Config::loadFromLocalFile(const std::string &u) return f; } -AFILE * Config::loadFromRemoteFile(const std::string &u) -{ - logger->info("Reading configuration from remote URI: {}", u); - - AFILE *f = afopen(u.c_str(), "r"); - if (!f) - throw RuntimeError("Failed to open configuration from: {}", u); - - return f; -} - json_t * Config::decode(FILE *f) { json_error_t err; diff --git a/lib/dumper.cpp b/lib/dumper.cpp index cc6786f95..fa9443156 100644 --- a/lib/dumper.cpp +++ b/lib/dumper.cpp @@ -29,7 +29,6 @@ #include #include -#include using namespace villas; using namespace villas::node; @@ -37,7 +36,8 @@ using namespace villas::node; Dumper::Dumper(const std::string &socketNameIn) : socketName(socketNameIn), supressRepeatedWarning(true), - warningCounter(0) + warningCounter(0), + logger(logging.get("dumper")) { openSocket(); } @@ -50,7 +50,7 @@ int Dumper::openSocket() { socketFd = socket(AF_LOCAL, SOCK_STREAM, 0); if (socketFd < 0) { - info("Error creating socket %s", socketName.c_str()); + logger->info("Error creating socket {}", socketName); return -1; } @@ -89,7 +89,7 @@ void Dumper::writeData(unsigned len, double *yData, double *xData) auto str = ss.str(); auto bytesWritten = write(socketFd, str.c_str(), str.length()); if ((long unsigned int) bytesWritten != str.length() && (!supressRepeatedWarning || warningCounter <1 )) { - warning("Could not send all content to socket %s", socketName.c_str()); + logger->warn("Could not send all content to socket {}", socketName); warningCounter++; } } diff --git a/lib/formats/json.cpp b/lib/formats/json.cpp index b014a0a9d..354a1bcfc 100644 --- a/lib/formats/json.cpp +++ b/lib/formats/json.cpp @@ -26,6 +26,9 @@ #include #include #include +#include + +using namespace villas; static enum SignalType json_detect_format(json_t *val) { @@ -203,11 +206,9 @@ static int json_unpack_sample(struct io *io, json_t *json_smp, struct sample *sm return -1; enum SignalType fmt = json_detect_format(json_value); - if (sig->type != fmt) { - error("Received invalid data type in JSON payload: Received %s, expected %s for signal %s (index %zu).", + if (sig->type != fmt) + throw RuntimeError("Received invalid data type in JSON payload: Received {}, expected {} for signal {} (index {}).", signal_type_to_str(fmt), signal_type_to_str(sig->type), sig->name, i); - return -2; - } ret = signal_data_parse_json(&smp->data[i], sig->type, json_value); if (ret) diff --git a/lib/formats/protobuf.cpp b/lib/formats/protobuf.cpp index 5bafb8c07..a2a0cf286 100644 --- a/lib/formats/protobuf.cpp +++ b/lib/formats/protobuf.cpp @@ -178,10 +178,8 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s smp->flags = 0; smp->signals = io->signals; - if (pb_smp->type != VILLAS__NODE__SAMPLE__TYPE__DATA) { - warning("Parsed non supported message type. Skipping"); - continue; - } + if (pb_smp->type != VILLAS__NODE__SAMPLE__TYPE__DATA) + throw RuntimeError("Parsed non supported message type. Skipping"); if (pb_smp->has_sequence) { smp->flags |= (int) SampleFlags::HAS_SEQUENCE; @@ -203,11 +201,9 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s if (!sig) return -1; - if (sig->type != fmt) { - error("Received invalid data type in Protobuf payload: Received %s, expected %s for signal %s (index %u).", + if (sig->type != fmt) + throw RuntimeError("Received invalid data type in Protobuf payload: Received {}, expected {} for signal {} (index {}).", signal_type_to_str(fmt), signal_type_to_str(sig->type), sig->name, i); - return -2; - } switch (sig->type) { case SignalType::FLOAT: diff --git a/lib/formats/raw.cpp b/lib/formats/raw.cpp index 6b1e56d06..3b74120dc 100644 --- a/lib/formats/raw.cpp +++ b/lib/formats/raw.cpp @@ -56,7 +56,7 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp int o = 0; size_t nlen; - void *vbuf = (char *) buf; // avoid warning about invalid pointer cast + void *vbuf = (char *) buf; /* Avoid warning about invalid pointer cast */ int8_t *i8 = (int8_t *) vbuf; int16_t *i16 = (int16_t *) vbuf; @@ -249,7 +249,7 @@ out: if (wbytes) int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt) { - void *vbuf = (void *) buf; // avoid warning about invalid pointer cast + void *vbuf = (void *) buf; /* Avoid warning about invalid pointer cast */ int8_t *i8 = (int8_t *) vbuf; int16_t *i16 = (int16_t *) vbuf; @@ -272,16 +272,12 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct if (cnt > 1) return -1; - if (len % (bits / 8)) { - warning("Invalid RAW Payload length: %#zx", len); - return -1; - } + if (len % (bits / 8)) + return -1; /* Invalid RAW Payload length */ if (io->flags & RAW_FAKE_HEADER) { - if (nlen < o + 3) { - warning("Received a packet with no fake header. Skipping..."); - return -1; - } + if (nlen < o + 3) + return -1; /* Received a packet with no fake header. Skipping... */ switch (bits) { case 8: @@ -397,17 +393,14 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct break; case SignalType::INVALID: - warning("Unsupported format in RAW payload"); - return -1; + return -1; /* Unsupported format in RAW payload */ } } smp->length = i; - if (smp->length > smp->capacity) { - warning("Received more values than supported: length=%u, capacity=%u", smp->length, smp->capacity); - smp->length = smp->capacity; - } + if (smp->length > smp->capacity) + smp->length = smp->capacity; /* Received more values than supported */ if (rbytes) *rbytes = o * (bits / 8); diff --git a/lib/formats/villas_binary.cpp b/lib/formats/villas_binary.cpp index c6d6ae44a..d21f9d31a 100644 --- a/lib/formats/villas_binary.cpp +++ b/lib/formats/villas_binary.cpp @@ -68,10 +68,8 @@ int villas_binary_sscan(struct io *io, const char *buf, size_t len, size_t *rbyt unsigned i = 0; const char *ptr = buf; - if (len % 4 != 0) { - warning("Packet size is invalid: %zd Must be multiple of 4 bytes.", len); - return -1; - } + if (len % 4 != 0) + return -1; /* Packet size is invalid: Must be multiple of 4 bytes */ for (i = 0; i < cnt; i++) { struct msg *msg = (struct msg *) ptr; @@ -84,18 +82,14 @@ int villas_binary_sscan(struct io *io, const char *buf, size_t len, size_t *rbyt break; /* Check if header is still in buffer bounaries */ - if (ptr + sizeof(struct msg) > buf + len) { - warning("Invalid msg received: reason=1"); - break; - } + if (ptr + sizeof(struct msg) > buf + len) + return -2; /* Invalid msg received */ values = (io->flags & VILLAS_BINARY_WEB) ? msg->length : ntohs(msg->length); /* Check if remainder of message is in buffer boundaries */ - if (ptr + MSG_LEN(values) > buf + len) { - warning("Invalid msg received: reason=2, msglen=%zu, len=%zu, ptr=%p, buf=%p, i=%u", MSG_LEN(values), len, ptr, buf, i); - break; - } + if (ptr + MSG_LEN(values) > buf + len) + return -3; /*Invalid msg receive */ if (io->flags & VILLAS_BINARY_WEB) { /** @todo convert from little endian */ @@ -104,10 +98,8 @@ int villas_binary_sscan(struct io *io, const char *buf, size_t len, size_t *rbyt msg_ntoh(msg); ret = msg_to_sample(msg, smp, io->signals); - if (ret) { - warning("Invalid msg received: reason=3, ret=%d", ret); - break; - } + if (ret) + return ret; /* Invalid msg received */ ptr += MSG_LEN(smp->length); } diff --git a/lib/hook.cpp b/lib/hook.cpp index cefaa95b2..c649e7bdf 100644 --- a/lib/hook.cpp +++ b/lib/hook.cpp @@ -46,7 +46,7 @@ Hook::Hook(struct vpath *p, struct vnode *n, int fl, int prio, bool en) : enabled(en), path(p), node(n), - cfg(nullptr) + config(nullptr) { int ret; @@ -80,21 +80,21 @@ void Hook::prepare(struct vlist *sigs) state = State::PREPARED; } -void Hook::parse(json_t *c) +void Hook::parse(json_t *json) { int ret; json_error_t err; assert(state != State::STARTED); - ret = json_unpack_ex(c, &err, 0, "{ s?: i, s?: b }", + ret = json_unpack_ex(json, &err, 0, "{ s?: i, s?: b }", "priority", &priority, "enabled", &enabled ); if (ret) - throw ConfigError(c, err, "node-config-hook"); + throw ConfigError(json, err, "node-config-hook"); - cfg = c; + config = json; state = State::PARSED; } diff --git a/lib/hook_list.cpp b/lib/hook_list.cpp index b1cd544fa..5597a3e69 100644 --- a/lib/hook_list.cpp +++ b/lib/hook_list.cpp @@ -25,12 +25,11 @@ #include #include #include -#include using namespace villas; using namespace villas::node; -int hook_list_init(vlist *hs) +int hook_list_init(struct vlist *hs) { int ret; @@ -48,7 +47,7 @@ static int hook_destroy(Hook *h) return 0; } -int hook_list_destroy(vlist *hs) +int hook_list_destroy(struct vlist *hs) { int ret; @@ -59,14 +58,14 @@ int hook_list_destroy(vlist *hs) return 0; } -void hook_list_parse(vlist *hs, json_t *cfg, int mask, struct vpath *o, struct vnode *n) +void hook_list_parse(struct vlist *hs, json_t *json, int mask, struct vpath *o, struct vnode *n) { - if (!json_is_array(cfg)) - throw ConfigError(cfg, "node-config-hook", "Hooks must be configured as a list of hook objects"); + if (!json_is_array(json)) + throw ConfigError(json, "node-config-hook", "Hooks must be configured as a list of hook objects"); size_t i; json_t *json_hook; - json_array_foreach(cfg, i, json_hook) { + json_array_foreach(json, i, json_hook) { int ret; const char *type; Hook *h; @@ -101,7 +100,7 @@ static int hook_is_enabled(const Hook *h) return h->isEnabled() ? 0 : -1; } -void hook_list_prepare(vlist *hs, vlist *sigs, int m, struct vpath *p, struct vnode *n) +void hook_list_prepare(struct vlist *hs, vlist *sigs, int m, struct vpath *p, struct vnode *n) { assert(hs->state == State::INITIALIZED); @@ -131,11 +130,12 @@ skip_add: sigs = h->getSignals(); - signal_list_dump(sigs); + auto logger = logging.get("hook"); + signal_list_dump(logger, sigs); } } -int hook_list_process(vlist *hs, sample *smps[], unsigned cnt) +int hook_list_process(struct vlist *hs, struct sample *smps[], unsigned cnt) { unsigned current, processed = 0; @@ -172,7 +172,7 @@ skip: {} stop: return processed; } -void hook_list_periodic(vlist *hs) +void hook_list_periodic(struct vlist *hs) { for (size_t j = 0; j < vlist_length(hs); j++) { Hook *h = (Hook *) vlist_at(hs, j); @@ -181,7 +181,7 @@ void hook_list_periodic(vlist *hs) } } -void hook_list_start(vlist *hs) +void hook_list_start(struct vlist *hs) { for (size_t i = 0; i < vlist_length(hs); i++) { Hook *h = (Hook *) vlist_at(hs, i); @@ -190,7 +190,7 @@ void hook_list_start(vlist *hs) } } -void hook_list_stop(vlist *hs) +void hook_list_stop(struct vlist *hs) { for (size_t i = 0; i < vlist_length(hs); i++) { Hook *h = (Hook *) vlist_at(hs, i); @@ -199,14 +199,14 @@ void hook_list_stop(vlist *hs) } } -vlist * hook_list_get_signals(vlist *hs) +struct vlist * hook_list_get_signals(struct vlist *hs) { Hook *h = (Hook *) vlist_last(hs); return h->getSignals(); } -json_t * hook_list_to_json(vlist *hs) +json_t * hook_list_to_json(struct vlist *hs) { json_t *json_hooks = json_array(); @@ -217,4 +217,4 @@ json_t * hook_list_to_json(vlist *hs) } return json_hooks; -} \ No newline at end of file +} diff --git a/lib/hooks/average.cpp b/lib/hooks/average.cpp index c89cac123..a9e157a6c 100644 --- a/lib/hooks/average.cpp +++ b/lib/hooks/average.cpp @@ -98,7 +98,7 @@ public: state = State::PREPARED; } - virtual void parse(json_t *cfg) + virtual void parse(json_t *json) { int ret; size_t i; @@ -107,14 +107,14 @@ public: assert(state != State::STARTED); - Hook::parse(cfg); + Hook::parse(json); - ret = json_unpack_ex(cfg, &err, 0, "{ s: i, s: o }", + ret = json_unpack_ex(json, &err, 0, "{ s: i, s: o }", "offset", &offset, "signals", &json_signals ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-average"); + throw ConfigError(json, err, "node-config-hook-average"); if (!json_is_array(json_signals)) throw ConfigError(json_signals, "node-config-hook-average-signals", "Setting 'signals' must be a list of signal names"); diff --git a/lib/hooks/cast.cpp b/lib/hooks/cast.cpp index 1f1203bd2..4cf521646 100644 --- a/lib/hooks/cast.cpp +++ b/lib/hooks/cast.cpp @@ -96,7 +96,7 @@ public: state = State::PREPARED; } - virtual void parse(json_t *cfg) + virtual void parse(json_t *json) { int ret; @@ -105,20 +105,20 @@ public: assert(state != State::STARTED); - Hook::parse(cfg); + Hook::parse(json); const char *name = nullptr; const char *unit = nullptr; const char *type = nullptr; - ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s?: s, s?: s, s?: s }", + ret = json_unpack_ex(json, &err, 0, "{ s: o, s?: s, s?: s, s?: s }", "signal", &json_signal, "new_type", &type, "new_name", &name, "new_unit", &unit ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-cast"); + throw ConfigError(json, err, "node-config-hook-cast"); switch (json_typeof(json_signal)) { case JSON_STRING: diff --git a/lib/hooks/decimate.cpp b/lib/hooks/decimate.cpp index 2fce59e22..6607e8c3b 100644 --- a/lib/hooks/decimate.cpp +++ b/lib/hooks/decimate.cpp @@ -38,20 +38,20 @@ void DecimateHook::start() state = State::STARTED; } -void DecimateHook::parse(json_t *cfg) +void DecimateHook::parse(json_t *json) { int ret; json_error_t err; assert(state != State::STARTED); - Hook::parse(cfg); + Hook::parse(json); - ret = json_unpack_ex(cfg, &err, 0, "{ s: i }", + ret = json_unpack_ex(json, &err, 0, "{ s: i }", "ratio", &ratio ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-decimate"); + throw ConfigError(json, err, "node-config-hook-decimate"); state = State::PARSED; } diff --git a/lib/hooks/dft.cpp b/lib/hooks/dft.cpp index b080eafc9..ea2545d76 100644 --- a/lib/hooks/dft.cpp +++ b/lib/hooks/dft.cpp @@ -235,13 +235,13 @@ public: signalIndex.push_back(idx); } else - warning("Could not parse channel list. Please check documentation for syntax"); + logger->warn("Could not parse channel list. Please check documentation for syntax"); } else throw ConfigError(jsonChannelList, "node-config-node-signal", "No parameter signalIndex given."); if (!windowTypeC) { - info("No Window type given, assume no windowing"); + logger->info("No Window type given, assume no windowing"); windowType = WindowType::NONE; } else if (strcmp(windowTypeC, "flattop") == 0) @@ -251,18 +251,18 @@ public: else if (strcmp(windowTypeC, "hann") == 0) windowType = WindowType::HANN; else { - info("Window type %s not recognized, assume no windowing", windowTypeC); + logger->info("Window type {} not recognized, assume no windowing", windowTypeC); windowType = WindowType::NONE; } if (!paddingTypeC) { - info("No Padding type given, assume no zeropadding"); + logger->info("No Padding type given, assume no zeropadding"); paddingType = PaddingType::ZERO; } else if (strcmp(paddingTypeC, "signal_repeat") == 0) paddingType = PaddingType::SIG_REPEAT; else { - info("Padding type %s not recognized, assume zero padding", paddingTypeC); + logger->info("Padding type {} not recognized, assume zero padding", paddingTypeC); paddingType = PaddingType::ZERO; } @@ -326,7 +326,7 @@ public: } if ((smp->sequence - lastSequence) > 1) - warning("Calculation is not Realtime. %" PRIu64 " sampled missed", smp->sequence - lastSequence); + logger->warn("Calculation is not Realtime. {} sampled missed", smp->sequence - lastSequence); lastSequence = smp->sequence; diff --git a/lib/hooks/dp.cpp b/lib/hooks/dp.cpp index b89c1b87b..09a7bf7e3 100644 --- a/lib/hooks/dp.cpp +++ b/lib/hooks/dp.cpp @@ -159,18 +159,18 @@ public: state = State::STARTED; } - virtual void parse(json_t *cfg) + virtual void parse(json_t *json) { int ret; json_error_t err; json_t *json_harmonics, *json_harmonic, *json_signal; size_t i; - Hook::parse(cfg); + Hook::parse(json); double rate = -1, dt = -1; - ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s: F, s?: F, s?: F, s: o, s?: b }", + ret = json_unpack_ex(json, &err, 0, "{ s: o, s: F, s?: F, s?: F, s: o, s?: b }", "signal", &json_signal, "f0", &f0, "dt", &dt, @@ -179,14 +179,14 @@ public: "inverse", &inverse ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-dp"); + throw ConfigError(json, err, "node-config-hook-dp"); if (rate > 0) timestep = 1. / rate; else if (dt > 0) timestep = dt; else - throw ConfigError(cfg, "node-config-hook-dp", "Either on of the settings 'dt' or 'rate' must be given"); + throw ConfigError(json, "node-config-hook-dp", "Either on of the settings 'dt' or 'rate' must be given"); if (!json_is_array(json_harmonics)) throw ConfigError(json_harmonics, "node-config-hook-dp-harmonics", "Setting 'harmonics' must be a list of integers"); diff --git a/lib/hooks/dump.cpp b/lib/hooks/dump.cpp index f0f66bcf2..b4a780c6c 100644 --- a/lib/hooks/dump.cpp +++ b/lib/hooks/dump.cpp @@ -41,7 +41,7 @@ public: { assert(state == State::STARTED); - sample_dump(smp); + sample_dump(logger, smp); return Reason::OK; } diff --git a/lib/hooks/ebm.cpp b/lib/hooks/ebm.cpp index 33d2340b8..533482ceb 100644 --- a/lib/hooks/ebm.cpp +++ b/lib/hooks/ebm.cpp @@ -27,7 +27,6 @@ #include #include -#include #include #include @@ -46,7 +45,7 @@ protected: public: using Hook::Hook; - virtual void parse(json_t *cfg) + virtual void parse(json_t *json) { int ret; @@ -54,13 +53,13 @@ public: json_error_t err; json_t *json_phases, *json_phase; - Hook::parse(cfg); + Hook::parse(json); - ret = json_unpack_ex(cfg, &err, 0, "{ s: o }", + ret = json_unpack_ex(json, &err, 0, "{ s: o }", "phases", &json_phases ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-ebm"); + throw ConfigError(json, err, "node-config-hook-ebm"); if (!json_is_array(json_phases)) throw ConfigError(json_phases, "node-config-hook-ebm-phases"); @@ -72,7 +71,7 @@ public: &voltage, ¤t ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-ebm-phases"); + throw ConfigError(json, err, "node-config-hook-ebm-phases"); phases.emplace_back(voltage, current); } @@ -94,7 +93,7 @@ public: { assert(state == State::STARTED); - info("Energy: %f", energy); + logger->info("Energy: {}", energy); } virtual Hook::Reason process(sample *smp) diff --git a/lib/hooks/gate.cpp b/lib/hooks/gate.cpp index 4d66e2ef2..5303f33eb 100644 --- a/lib/hooks/gate.cpp +++ b/lib/hooks/gate.cpp @@ -71,7 +71,7 @@ public: startSequence(0) { } - virtual void parse(json_t *cfg) + virtual void parse(json_t *json) { int ret; @@ -82,9 +82,9 @@ public: assert(state != State::STARTED); - Hook::parse(cfg); + Hook::parse(json); - ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s?: F, s?: F, s?: i, s?: s }", + ret = json_unpack_ex(json, &err, 0, "{ s: o, s?: F, s?: F, s?: i, s?: s }", "signal", &json_signal, "threshold", &threshold, "duration", &duration, @@ -92,7 +92,7 @@ public: "mode", &mode_str ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-gate"); + throw ConfigError(json, err, "node-config-hook-gate"); if (mode_str) { if (!strcmp(mode_str, "above")) diff --git a/lib/hooks/jitter_calc.cpp b/lib/hooks/jitter_calc.cpp index 618588ad2..edf67274f 100644 --- a/lib/hooks/jitter_calc.cpp +++ b/lib/hooks/jitter_calc.cpp @@ -98,7 +98,10 @@ public: */ jitter_val[(curr_count + 1) % GPS_NTP_DELAY_WIN_SIZE] = jitter_val[curr_count] + (labs(curr_delay_us) - jitter_val[curr_count]) / 16; - logger->info("{}: jitter={} usec, moving average={} usec, moving variance={} usec", __FUNCTION__, jitter_val[(curr_count + 1) % GPS_NTP_DELAY_WIN_SIZE], moving_avg[curr_count], moving_var[curr_count]); + logger->info("{}: jitter={} usec, moving average={} usec, moving variance={} usec", __FUNCTION__, + jitter_val[(curr_count + 1) % GPS_NTP_DELAY_WIN_SIZE], + moving_avg[curr_count], + moving_var[curr_count]); curr_count++; if (curr_count >= GPS_NTP_DELAY_WIN_SIZE) diff --git a/lib/hooks/limit_rate.cpp b/lib/hooks/limit_rate.cpp index 41bb5c9ca..1a05ec368 100644 --- a/lib/hooks/limit_rate.cpp +++ b/lib/hooks/limit_rate.cpp @@ -33,7 +33,7 @@ namespace villas { namespace node { -void LimitRateHook::parse(json_t *cfg) +void LimitRateHook::parse(json_t *json) { int ret; json_error_t err; @@ -43,14 +43,14 @@ void LimitRateHook::parse(json_t *cfg) double rate; const char *m = nullptr; - Hook::parse(cfg); + Hook::parse(json); - ret = json_unpack_ex(cfg, &err, 0, "{ s: F, s?: s }", + ret = json_unpack_ex(json, &err, 0, "{ s: F, s?: s }", "rate", &rate, "mode", &m ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-limit_rate"); + throw ConfigError(json, err, "node-config-hook-limit_rate"); if (m) { if (!strcmp(m, "origin")) @@ -60,7 +60,7 @@ void LimitRateHook::parse(json_t *cfg) else if (!strcmp(m, "local")) mode = LIMIT_RATE_LOCAL; else - throw ConfigError(cfg, "node-config-hook-limit_rate-mode", "Invalid value '{}' for setting 'mode'", mode); + throw ConfigError(json, "node-config-hook-limit_rate-mode", "Invalid value '{}' for setting 'mode'", mode); } deadtime = 1.0 / rate; diff --git a/lib/hooks/limit_value.cpp b/lib/hooks/limit_value.cpp index 4095dc1dd..cd0412182 100644 --- a/lib/hooks/limit_value.cpp +++ b/lib/hooks/limit_value.cpp @@ -101,7 +101,7 @@ public: state = State::PREPARED; } - virtual void parse(json_t *cfg) + virtual void parse(json_t *json) { int ret; size_t i; @@ -110,15 +110,15 @@ public: assert(state != State::STARTED); - Hook::parse(cfg); + Hook::parse(json); - ret = json_unpack_ex(cfg, &err, 0, "{ s: f, s: f, s: o }", + ret = json_unpack_ex(json, &err, 0, "{ s: f, s: f, s: o }", "min", &min, "min", &max, "signals", &json_signals ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-average"); + throw ConfigError(json, err, "node-config-hook-average"); if (!json_is_array(json_signals)) throw ConfigError(json_signals, "node-config-hook-average-signals", "Setting 'signals' must be a list of signal names"); diff --git a/lib/hooks/lua.cpp b/lib/hooks/lua.cpp index 2d1802e1a..2d0d60fbc 100644 --- a/lib/hooks/lua.cpp +++ b/lib/hooks/lua.cpp @@ -139,13 +139,10 @@ lua_tosignaldata(lua_State *L, union signal_data *data, enum SignalType targetTy break; default: - warning("Failed to convert Lua type %s to signal data", lua_typename(L, luaType)); return; } signal_data_cast(data, type, targetType); - - return; } static void @@ -472,7 +469,7 @@ LuaHook::parseExpressions(json_t *json_sigs) } void -LuaHook::parse(json_t *c) +LuaHook::parse(json_t *json) { int ret; const char *script_str = nullptr; @@ -482,15 +479,15 @@ LuaHook::parse(json_t *c) assert(state != State::STARTED); - Hook::parse(c); + Hook::parse(json); - ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: o, s?: b }", + ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: o, s?: b }", "script", &script_str, "signals", &json_signals, "use_names", &names ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-lua"); + throw ConfigError(json, err, "node-config-hook-lua"); useNames = names; @@ -522,7 +519,7 @@ LuaHook::lookupFunctions() ret = lua_type(L, -1); if (ret == LUA_TFUNCTION) { - logger->debug("Found Lua function: %s()", it.first); + logger->debug("Found Lua function: {}()", it.first); *(it.second) = lua_gettop(L); } else { @@ -602,7 +599,7 @@ LuaHook::prepare() luaL_openlibs(L); /* Load our Lua script */ - logger->debug("Loading Lua script: %s", script.c_str()); + logger->debug("Loading Lua script: {}", script); setupEnvironment(); loadScript(); @@ -640,7 +637,7 @@ LuaHook::prepare() logger->debug("Executing Lua function: prepare()"); lua_pushvalue(L, functions.prepare); - lua_pushjson(L, cfg); + lua_pushjson(L, config); int ret = lua_pcall(L, 1, 0, 0); if (ret) throw LuaError(L, ret); diff --git a/lib/hooks/pps_ts.cpp b/lib/hooks/pps_ts.cpp index f422e227a..89267c1fa 100644 --- a/lib/hooks/pps_ts.cpp +++ b/lib/hooks/pps_ts.cpp @@ -30,7 +30,6 @@ #include #include #include -#include namespace villas { namespace node { @@ -78,28 +77,27 @@ public: filterWindow(horizonEst + 1, 0) { } - virtual void parse(json_t *cfg) + virtual void parse(json_t *json) { int ret; json_error_t err; assert(state != State::STARTED); - Hook::parse(cfg); + Hook::parse(json); double fSmps = 0; - ret = json_unpack_ex(cfg, &err, 0, "{ s: i, s?: f, s: F}", + ret = json_unpack_ex(json, &err, 0, "{ s: i, s?: f, s: F}", "signal_index", &idx, "threshold", &thresh, "expected_smp_rate", &fSmps ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-pps_ts"); + throw ConfigError(json, err, "node-config-hook-pps_ts"); period = 1.0 / fSmps; - debug(LOG_HOOK | 5, "parsed config thresh=%f signal_index=%d nominal_period=%f", thresh, idx, period); - + logger->debug("Parsed config thresh={} signal_index={} nominal_period={}", thresh, idx, period); state = State::PARSED; } @@ -142,7 +140,7 @@ public: cntSmps = 0; cntEdges++; - debug(LOG_HOOK | 5, "Time Error is: %f periodEst %f periodErrComp %f", timeError, periodEst, periodErrComp); + logger->debug("Time Error is: {} periodEst {} periodErrComp {}", timeError, periodEst, periodErrComp); } cntSmps++; @@ -159,7 +157,7 @@ public: if ((smp->sequence - lastSequence) > 1) - warning("Samples missed: %" PRIu64 " sampled missed", smp->sequence - lastSequence); + logger->warn("Samples missed: {} sampled missed", smp->sequence - lastSequence); lastSequence = smp->sequence; diff --git a/lib/hooks/print.cpp b/lib/hooks/print.cpp index d96380206..06c390ef1 100644 --- a/lib/hooks/print.cpp +++ b/lib/hooks/print.cpp @@ -88,7 +88,7 @@ public: state = State::STOPPED; } - virtual void parse(json_t *cfg) + virtual void parse(json_t *json) { const char *f = nullptr, *p = nullptr, *u = nullptr; int ret; @@ -96,15 +96,15 @@ public: assert(state != State::STARTED); - Hook::parse(cfg); + Hook::parse(json); - ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: s, s?: s }", + ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: s, s?: s }", "output", &u, "prefix", &p, "format", &f ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-print"); + throw ConfigError(json, err, "node-config-hook-print"); if (p) prefix = strdup(p); @@ -115,7 +115,7 @@ public: if (f) { format = format_type_lookup(f); if (!format) - throw ConfigError(cfg, "node-config-hook-print-format", "Invalid IO format '{}'", f); + throw ConfigError(json, "node-config-hook-print-format", "Invalid IO format '{}'", f); } state = State::PARSED; diff --git a/lib/hooks/scale.cpp b/lib/hooks/scale.cpp index aa8caa36b..3f367e4d5 100644 --- a/lib/hooks/scale.cpp +++ b/lib/hooks/scale.cpp @@ -69,7 +69,7 @@ public: free(signal_name); } - virtual void parse(json_t *cfg) + virtual void parse(json_t *json) { int ret; json_t *json_signal; @@ -77,15 +77,15 @@ public: assert(state != State::STARTED); - Hook::parse(cfg); + Hook::parse(json); - ret = json_unpack_ex(cfg, &err, 0, "{ s?: F, s?: F, s: o }", + ret = json_unpack_ex(json, &err, 0, "{ s?: F, s?: F, s: o }", "scale", &scale, "offset", &offset, "signal", &json_signal ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-scale"); + throw ConfigError(json, err, "node-config-hook-scale"); switch (json_typeof(json_signal)) { case JSON_STRING: diff --git a/lib/hooks/shift_seq.cpp b/lib/hooks/shift_seq.cpp index 390023c5b..69a592047 100644 --- a/lib/hooks/shift_seq.cpp +++ b/lib/hooks/shift_seq.cpp @@ -39,20 +39,20 @@ public: using Hook::Hook; - virtual void parse(json_t *cfg) + virtual void parse(json_t *json) { json_error_t err; int ret; assert(state != State::STARTED); - Hook::parse(cfg); + Hook::parse(json); - ret = json_unpack_ex(cfg, &err, 0, "{ s: i }", + ret = json_unpack_ex(json, &err, 0, "{ s: i }", "offset", &offset ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-shift_seq"); + throw ConfigError(json, err, "node-config-hook-shift_seq"); state = State::PARSED; } diff --git a/lib/hooks/shift_ts.cpp b/lib/hooks/shift_ts.cpp index 2172d7c3b..78bd318fd 100644 --- a/lib/hooks/shift_ts.cpp +++ b/lib/hooks/shift_ts.cpp @@ -48,7 +48,7 @@ public: mode(SHIFT_ORIGIN) { } - virtual void parse(json_t *cfg) + virtual void parse(json_t *json) { double o; const char *m = nullptr; @@ -57,14 +57,14 @@ public: assert(state != State::STARTED); - Hook::parse(cfg); + Hook::parse(json); - ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s: F }", + ret = json_unpack_ex(json, &err, 0, "{ s?: s, s: F }", "mode", &m, "offset", &o ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-shift_ts"); + throw ConfigError(json, err, "node-config-hook-shift_ts"); if (m) { if (!strcmp(m, "origin")) @@ -72,7 +72,7 @@ public: else if (!strcmp(m, "received")) mode = SHIFT_RECEIVED; else - throw ConfigError(cfg, "node-config-hook-shift_ts-mode", "Invalid mode parameter '{}'", m); + throw ConfigError(json, "node-config-hook-shift_ts-mode", "Invalid mode parameter '{}'", m); } offset = time_from_double(o); diff --git a/lib/hooks/skip_first.cpp b/lib/hooks/skip_first.cpp index 555040df9..f055514f4 100644 --- a/lib/hooks/skip_first.cpp +++ b/lib/hooks/skip_first.cpp @@ -60,7 +60,7 @@ protected: public: using Hook::Hook; - virtual void parse(json_t *cfg) + virtual void parse(json_t *json) { double s; @@ -69,9 +69,9 @@ public: assert(state != State::STARTED); - Hook::parse(cfg); + Hook::parse(json); - ret = json_unpack_ex(cfg, &err, 0, "{ s: F }", "seconds", &s); + ret = json_unpack_ex(json, &err, 0, "{ s: F }", "seconds", &s); if (!ret) { seconds.wait = time_from_double(s); mode = Mode::SECONDS; @@ -80,7 +80,7 @@ public: return; } - ret = json_unpack_ex(cfg, &err, 0, "{ s: i }", "samples", &samples.wait); + ret = json_unpack_ex(json, &err, 0, "{ s: i }", "samples", &samples.wait); if (!ret) { mode = Mode::SAMPLES; @@ -88,7 +88,7 @@ public: return; } - throw ConfigError(cfg, err, "node-config-hook-skip_first"); + throw ConfigError(json, err, "node-config-hook-skip_first"); } virtual void start() diff --git a/lib/hooks/stats.cpp b/lib/hooks/stats.cpp index 56db378ab..d43643f5a 100644 --- a/lib/hooks/stats.cpp +++ b/lib/hooks/stats.cpp @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -109,7 +108,7 @@ protected: std::shared_ptr stats; - AFILE *output; + FILE *output; std::string uri; public: @@ -144,7 +143,7 @@ public: assert(state == State::PREPARED); if (!uri.empty()) { - output = afopen(uri.c_str(), "w+"); + output = fopen(uri.c_str(), "w+"); if (!output) throw RuntimeError("Failed to open file '{}' for writing", uri); } @@ -156,10 +155,10 @@ public: { assert(state == State::STARTED); - stats->print(uri.empty() ? stdout : output->file, format, verbose); + stats->print(uri.empty() ? stdout : output, format, verbose); if (!uri.empty()) - afclose(output); + fclose(output); state = State::STOPPED; } @@ -184,22 +183,22 @@ public: { assert(state == State::STARTED); - stats->printPeriodic(uri.empty() ? stdout : output->file, format, node); + stats->printPeriodic(uri.empty() ? stdout : output, format, node); } - virtual void parse(json_t *cfg) + virtual void parse(json_t *json) { int ret; json_error_t err; assert(state != State::STARTED); - Hook::parse(cfg); + Hook::parse(json); const char *f = nullptr; const char *u = nullptr; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: b, s?: i, s?: i, s?: s }", + ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: b, s?: i, s?: i, s?: s }", "format", &f, "verbose", &verbose, "warmup", &warmup, @@ -207,13 +206,13 @@ public: "output", &u ); if (ret) - throw ConfigError(cfg, err, "node-config-hook-stats"); + throw ConfigError(json, err, "node-config-hook-stats"); if (f) { try { format = Stats::lookupFormat(f); } catch (const std::invalid_argument &e) { - throw ConfigError(cfg, "node-config-hook-stats", "Invalid statistic output format: {}", f); + throw ConfigError(json, "node-config-hook-stats", "Invalid statistic output format: {}", f); } } diff --git a/lib/io.cpp b/lib/io.cpp index cef01c798..47f4f0402 100644 --- a/lib/io.cpp +++ b/lib/io.cpp @@ -171,35 +171,24 @@ int io_stream_open(struct io *io, const char *uri) if (!strcmp(uri, "-")) { goto stdio; } - else if (aislocal(uri) == 1) { + else { io->mode = IOMode::STDIO; - io->out.stream.std = fopen(uri, "a+"); - if (io->out.stream.std == nullptr) + io->out.stream = fopen(uri, "a+"); + if (io->out.stream == nullptr) return -1; - io->in.stream.std = fopen(uri, "r"); - if (io->in.stream.std == nullptr) + io->in.stream = fopen(uri, "r"); + if (io->in.stream == nullptr) return -1; } - else { - io->mode = IOMode::ADVIO; - - io->out.stream.adv = afopen(uri, "a+"); - if (io->out.stream.adv == nullptr) - return -1; - - io->in.stream.adv = afopen(uri, "a+"); - if (io->in.stream.adv == nullptr) - return -2; - } } else { stdio: io->mode = IOMode::STDIO; io->flags |= (int) IOFlags::FLUSH; - io->in.stream.std = stdin; - io->out.stream.std = stdout; + io->in.stream = stdin; + io->out.stream = stdout; } /* Make stream non-blocking if desired */ @@ -223,11 +212,11 @@ stdio: io->mode = IOMode::STDIO; /* Enable line buffering on stdio */ if (io->mode == IOMode::STDIO) { - ret = setvbuf(io->in.stream.std, nullptr, _IOLBF, BUFSIZ); + ret = setvbuf(io->in.stream, nullptr, _IOLBF, BUFSIZ); if (ret) return -1; - ret = setvbuf(io->out.stream.std, nullptr, _IOLBF, BUFSIZ); + ret = setvbuf(io->out.stream, nullptr, _IOLBF, BUFSIZ); if (ret) return -1; } @@ -240,26 +229,15 @@ int io_stream_close(struct io *io) int ret; switch (io->mode) { - case IOMode::ADVIO: - ret = afclose(io->in.stream.adv); - if (ret) - return ret; - - ret = afclose(io->out.stream.adv); - if (ret) - return ret; - - return 0; - case IOMode::STDIO: - if (io->in.stream.std == stdin) + if (io->in.stream == stdin) return 0; - ret = fclose(io->in.stream.std); + ret = fclose(io->in.stream); if (ret) return ret; - ret = fclose(io->out.stream.std); + ret = fclose(io->out.stream); if (ret) return ret; @@ -275,10 +253,8 @@ int io_stream_close(struct io *io) int io_stream_flush(struct io *io) { switch (io->mode) { - case IOMode::ADVIO: - return afflush(io->out.stream.adv); case IOMode::STDIO: - return fflush(io->out.stream.std); + return fflush(io->out.stream); case IOMode::CUSTOM: return 0; } @@ -289,10 +265,8 @@ int io_stream_flush(struct io *io) int io_stream_eof(struct io *io) { switch (io->mode) { - case IOMode::ADVIO: - return afeof(io->in.stream.adv); case IOMode::STDIO: - return feof(io->in.stream.std); + return feof(io->in.stream); case IOMode::CUSTOM: return 0; } @@ -303,11 +277,8 @@ int io_stream_eof(struct io *io) void io_stream_rewind(struct io *io) { switch (io->mode) { - case IOMode::ADVIO: - arewind(io->in.stream.adv); - break; case IOMode::STDIO: - rewind(io->in.stream.std); + rewind(io->in.stream); break; case IOMode::CUSTOM: { } } @@ -316,10 +287,8 @@ void io_stream_rewind(struct io *io) int io_stream_fd(struct io *io) { switch (io->mode) { - case IOMode::ADVIO: - return afileno(io->in.stream.adv); case IOMode::STDIO: - return fileno(io->in.stream.std); + return fileno(io->in.stream); case IOMode::CUSTOM: return -1; } @@ -482,18 +451,14 @@ FILE * io_stream_output(struct io *io) { if (io->state != State::OPENED) return 0; - return io->mode == IOMode::ADVIO - ? io->out.stream.adv->file - : io->out.stream.std; + return io->out.stream; } FILE * io_stream_input(struct io *io) { if (io->state != State::OPENED) return 0; - return io->mode == IOMode::ADVIO - ? io->in.stream.adv->file - : io->in.stream.std; + return io->in.stream; } int io_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt) diff --git a/lib/kernel/nl.cpp b/lib/kernel/nl.cpp index 1e8d04afe..8ec80e17f 100644 --- a/lib/kernel/nl.cpp +++ b/lib/kernel/nl.cpp @@ -51,13 +51,13 @@ struct nl_sock * villas::kernel::nl::init() ret = nl_connect(sock, NETLINK_ROUTE); if (ret) - error("Failed to connect to kernel: %s", nl_geterror(ret)); + throw RuntimeError("Failed to connect to kernel: {}", nl_geterror(ret)); /* Fill some caches */ struct nl_cache *cache; ret = rtnl_link_alloc_cache(sock, AF_UNSPEC, &cache); if (ret) - error("Failed to get list of interfaces: %s", nl_geterror(ret)); + throw RuntimeError("Failed to get list of interfaces: {}", nl_geterror(ret)); nl_cache_mngt_provide(cache); } @@ -150,7 +150,7 @@ struct rtnl_link * villas::kernel::nl::get_egress_link(struct sockaddr *sa) ifindex = nl::get_egress(addr); nl_addr_put(addr); if (ifindex < 0) - error("Netlink error: %s", nl_geterror(ifindex)); + throw RuntimeError("Netlink error: {}", nl_geterror(ifindex)); break; } diff --git a/lib/kernel/tc.cpp b/lib/kernel/tc.cpp index 7e34be0ae..42997cfa9 100644 --- a/lib/kernel/tc.cpp +++ b/lib/kernel/tc.cpp @@ -28,7 +28,7 @@ #include #include - +#include #include #include #include @@ -45,7 +45,7 @@ int villas::kernel::tc::prio(Interface *i, struct rtnl_qdisc **qd, tc_hdl_t hand ret = kernel::module_load("sch_prio"); if (ret) - error("Failed to load kernel module: sch_prio (%d)", ret); + throw RuntimeError("Failed to load kernel module: sch_prio ({})", ret); /* This is the default priomap used by the tc-prio qdisc * We will use the first 'bands' bands internally */ @@ -65,7 +65,8 @@ int villas::kernel::tc::prio(Interface *i, struct rtnl_qdisc **qd, tc_hdl_t hand *qd = q; - debug(LOG_TC | 3, "Added prio qdisc with %d bands to interface '%s'", bands, rtnl_link_get_name(i->nl_link)); + auto logger = logging.get("kernel"); + logger->debug("Added prio qdisc with {} bands to interface '{}'", bands, rtnl_link_get_name(i->nl_link)); return ret; } @@ -78,7 +79,7 @@ int villas::kernel::tc::mark(Interface *i, struct rtnl_cls **cls, tc_hdl_t flowi ret = kernel::module_load("cls_fw"); if (ret) - error("Failed to load kernel module: cls_fw"); + throw RuntimeError("Failed to load kernel module: cls_fw"); rtnl_tc_set_link(TC_CAST(c), i->nl_link); rtnl_tc_set_handle(TC_CAST(c), mark); @@ -93,7 +94,8 @@ int villas::kernel::tc::mark(Interface *i, struct rtnl_cls **cls, tc_hdl_t flowi *cls = c; - debug(LOG_TC | 3, "Added fwmark classifier with mark %d to interface '%s'", mark, rtnl_link_get_name(i->nl_link)); + auto logger = logging.get("kernel"); + logger->debug("Added fwmark classifier with mark {} to interface '{}'", mark, rtnl_link_get_name(i->nl_link)); return ret; } diff --git a/lib/kernel/tc_netem.cpp b/lib/kernel/tc_netem.cpp index 16df90370..b02f3a54d 100644 --- a/lib/kernel/tc_netem.cpp +++ b/lib/kernel/tc_netem.cpp @@ -95,7 +95,7 @@ static int set_delay_distribution(struct rtnl_qdisc *qdisc, json_t *json) return 0; } -int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg) +int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *json) { int ret, val; @@ -110,7 +110,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg) json_error_t err; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o }", + ret = json_unpack_ex(json, &err, 0, "{ s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o }", "distribution", &json_delay_distribution, "correlation", &json_delay_correlation, "limit", &json_limit, @@ -121,7 +121,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg) "corruption", &json_corruption ); if (ret) - jerror(&err, "Failed to parse setting network emulation settings"); + throw ConfigError(json, err, "node-config-netem", "Failed to parse setting network emulation settings"); struct rtnl_qdisc *ne = rtnl_qdisc_alloc(); if (!ne) @@ -131,14 +131,14 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg) if (json_delay_distribution) { if (set_delay_distribution(ne, json_delay_distribution)) - error("Invalid delay distribution in netem config"); + throw ConfigError(json_delay_distribution, "Invalid delay distribution in netem config"); } if (json_delay_correlation) { double dval = json_number_value(json_delay_correlation); if (!json_is_number(json_delay_correlation) || dval < 0 || dval > 100) - error("Setting 'correlation' must be a positive integer within the range [ 0, 100 ]"); + throw ConfigError(json_delay_correlation, "Setting 'correlation' must be a positive integer within the range [ 0, 100 ]"); unsigned *pval = (unsigned *) &val; *pval = (unsigned) rint((dval / 100.) * max_percent_value); @@ -152,7 +152,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg) val = json_integer_value(json_limit); if (!json_is_integer(json_limit) || val <= 0) - error("Setting 'limit' must be a positive integer"); + throw ConfigError(json_limit, "Setting 'limit' must be a positive integer"); rtnl_netem_set_limit(ne, val); } @@ -163,7 +163,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg) val = json_integer_value(json_delay); if (!json_is_integer(json_delay) || val <= 0) - error("Setting 'delay' must be a positive integer"); + throw ConfigError(json_delay, "Setting 'delay' must be a positive integer"); rtnl_netem_set_delay(ne, val); } @@ -172,7 +172,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg) val = json_integer_value(json_jitter); if (!json_is_integer(json_jitter) || val <= 0) - error("Setting 'jitter' must be a positive integer"); + throw ConfigError(json_jitter, "Setting 'jitter' must be a positive integer"); rtnl_netem_set_jitter(ne, val); } @@ -181,7 +181,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg) double dval = json_number_value(json_loss); if (!json_is_number(json_loss) || dval < 0 || dval > 100) - error("Setting 'loss' must be a positive integer within the range [ 0, 100 ]"); + throw ConfigError(json_loss, "Setting 'loss' must be a positive integer within the range [ 0, 100 ]"); unsigned *pval = (unsigned *) &val; *pval = (unsigned) rint((dval / 100.) * max_percent_value); @@ -193,7 +193,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg) double dval = json_number_value(json_duplicate); if (!json_is_number(json_duplicate) || dval < 0 || dval > 100) - error("Setting 'duplicate' must be a positive integer within the range [ 0, 100 ]"); + throw ConfigError(json_duplicate, "Setting 'duplicate' must be a positive integer within the range [ 0, 100 ]"); unsigned *pval = (unsigned *) &val; *pval = (unsigned) rint((dval / 100.) * max_percent_value); @@ -205,7 +205,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg) double dval = json_number_value(json_corruption); if (!json_is_number(json_corruption) || dval < 0 || dval > 100) - error("Setting 'corruption' must be a positive integer within the range [ 0, 100 ]"); + throw ConfigError(json_corruption, "Setting 'corruption' must be a positive integer within the range [ 0, 100 ]"); unsigned *pval = (unsigned *) &val; *pval = (unsigned) rint((dval / 100.) * max_percent_value); @@ -275,7 +275,7 @@ int villas::kernel::tc::netem(Interface *i, struct rtnl_qdisc **qd, tc_hdl_t han ret = kernel::module_load("sch_netem"); if (ret) - error("Failed to load kernel module: sch_netem (%d)", ret); + throw RuntimeError("Failed to load kernel module: sch_netem ({})", ret); rtnl_tc_set_link(TC_CAST(q), i->nl_link); rtnl_tc_set_parent(TC_CAST(q), parent); @@ -286,7 +286,8 @@ int villas::kernel::tc::netem(Interface *i, struct rtnl_qdisc **qd, tc_hdl_t han *qd = q; - debug(LOG_TC | 3, "Added netem qdisc to interface '%s'", rtnl_link_get_name(i->nl_link)); + auto logger = logging.get("kernel"); + logger->debug("Added netem qdisc to interface '{}'", rtnl_link_get_name(i->nl_link)); return ret; } diff --git a/lib/mapping.cpp b/lib/mapping.cpp index e198a311c..85775d2d9 100644 --- a/lib/mapping.cpp +++ b/lib/mapping.cpp @@ -129,18 +129,18 @@ int mapping_entry_destroy(struct mapping_entry *me) return 0; } -int mapping_entry_parse(struct mapping_entry *me, json_t *cfg) +int mapping_entry_parse(struct mapping_entry *me, json_t *json) { const char *str; - str = json_string_value(cfg); + str = json_string_value(json); if (!str) return -1; return mapping_entry_parse_str(me, str); } -int mapping_list_parse(struct vlist *ml, json_t *cfg) +int mapping_list_parse(struct vlist *ml, json_t *json) { int ret; @@ -148,12 +148,12 @@ int mapping_list_parse(struct vlist *ml, json_t *cfg) json_t *json_entry; json_t *json_mapping; - if (json_is_string(cfg)) { + if (json_is_string(json)) { json_mapping = json_array(); - json_array_append(json_mapping, cfg); + json_array_append(json_mapping, json); } - else if (json_is_array(cfg)) - json_mapping = json_incref(cfg); + else if (json_is_array(json)) + json_mapping = json_incref(json); else return -1; diff --git a/lib/memory.cpp b/lib/memory.cpp index 27589c399..03271bc3e 100644 --- a/lib/memory.cpp +++ b/lib/memory.cpp @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include #include @@ -39,12 +39,15 @@ using namespace villas; static std::unordered_map allocations; +static Logger logger; int memory_init(int hugepages) { int ret; - info("Initialize memory sub-system: #hugepages=%d", hugepages); + logger = logging.get("memory"); + + logger->info("Initialize memory sub-system: #hugepages={}", hugepages); ret = memory_mmap_init(hugepages); if (ret < 0) @@ -76,8 +79,8 @@ int memory_lock(size_t lock) if (l.rlim_cur < lock) { if (l.rlim_max < lock) { if (getuid() != 0) { - warning("Failed to in increase ressource limit of locked memory. Please increase manually by running as root:"); - warning(" $ ulimit -Hl %zu", lock); + logger->warn("Failed to in increase ressource limit of locked memory. Please increase manually by running as root:"); + logger->warn(" $ ulimit -Hl {}", lock); return 0; } @@ -91,7 +94,7 @@ int memory_lock(size_t lock) if (ret) return ret; - debug(LOG_MEM | 2, "Increased ressource limit of locked memory to %zd bytes", lock); + logger->debug("Increased ressource limit of locked memory to {} bytes", lock); } #endif /* __arm__ */ @@ -116,13 +119,13 @@ void * memory_alloc_aligned(size_t len, size_t alignment, struct memory_type *m) { struct memory_allocation *ma = m->alloc(len, alignment, m); if (ma == nullptr) { - warning("Memory allocation of type %s failed. reason=%s", m->name, strerror(errno)); + logger->warn("Memory allocation of type {} failed. reason={}", m->name, strerror(errno)); return nullptr; } allocations[ma->address] = ma; - debug(LOG_MEM | 5, "Allocated %#zx bytes of %#zx-byte-aligned %s memory: %p", ma->length, ma->alignment, ma->type->name, ma->address); + logger->debug("Allocated {:#x} bytes of {:#x}-byte-aligned {} memory: {}", ma->length, ma->alignment, ma->type->name, ma->address); return ma->address; } @@ -136,7 +139,7 @@ int memory_free(void *ptr) if (!ma) return -1; - debug(LOG_MEM | 5, "Releasing %#zx bytes of %s memory: %p", ma->length, ma->type->name, ma->address); + logger->debug("Releasing {:#x} bytes of {} memory: {}", ma->length, ma->type->name, ma->address); ret = ma->type->free(ma, ma->type); if (ret) diff --git a/lib/memory/managed.cpp b/lib/memory/managed.cpp index db08b34e2..290b8f2c7 100644 --- a/lib/memory/managed.cpp +++ b/lib/memory/managed.cpp @@ -30,10 +30,10 @@ #include #include -#include #include #include #include +#include using namespace villas; using namespace villas::utils; @@ -166,7 +166,8 @@ struct memory_type * memory_managed(void *ptr, size_t len) char *cptr = (char *) ptr; if (len < sizeof(struct memory_type) + sizeof(struct memory_block)) { - info("memory_managed: passed region too small"); + auto logger = logging.get("memory:managed"); + logger->info("Passed region is too small"); return nullptr; } diff --git a/lib/memory/mmap.cpp b/lib/memory/mmap.cpp index 74ff0728b..d03e6a684 100644 --- a/lib/memory/mmap.cpp +++ b/lib/memory/mmap.cpp @@ -35,11 +35,11 @@ #endif /* __MACH__ */ #include -#include #include #include #include #include +#include using namespace villas; using namespace villas; @@ -47,9 +47,12 @@ using namespace villas::utils; static size_t pgsz = -1; static size_t hugepgsz = -1; +static Logger logger; int memory_mmap_init(int hugepages) { + logger = logging.get("memory:mmap"); + pgsz = kernel::get_page_size(); if (pgsz < 0) return -1; @@ -57,7 +60,7 @@ int memory_mmap_init(int hugepages) if (hugepages > 0) { hugepgsz = kernel::get_hugepage_size(); if (hugepgsz < 0) { - warning("Failed to determine hugepage size."); + logger->warn("Failed to determine hugepage size."); memory_default = &memory_mmap; return 0; @@ -71,16 +74,16 @@ int memory_mmap_init(int hugepages) if (getuid() == 0) { ret = kernel::set_nr_hugepages(hugepages); if (ret) { - warning("Failed to increase number of reserved hugepages"); + logger->warn("Failed to increase number of reserved hugepages"); memory_default = &memory_mmap; } - debug(LOG_MEM | 2, "Increased number of reserved hugepages from %d to %d", pagecnt, hugepages); + logger->debug("Increased number of reserved hugepages from {} to {}", pagecnt, hugepages); memory_default = &memory_mmap_hugetlb; } else { - warning("Failed to reserved hugepages. Please reserve manually by running as root:"); - warning(" $ echo %d > /proc/sys/vm/nr_hugepages", hugepages); + logger->warn("Failed to reserved hugepages. Please reserve manually by running as root:"); + logger->warn(" $ echo {} > /proc/sys/vm/nr_hugepages", hugepages); memory_default = &memory_mmap; } } @@ -91,7 +94,7 @@ int memory_mmap_init(int hugepages) #endif } else { - warning("Hugepage allocator disabled."); + logger->warn("Hugepage allocator disabled."); memory_default = &memory_mmap; } diff --git a/lib/node.cpp b/lib/node.cpp index 4836a5630..7878dbeaf 100644 --- a/lib/node.cpp +++ b/lib/node.cpp @@ -63,6 +63,9 @@ int node_init(struct vnode *n, struct vnode_type *vt) using stats_ptr = std::shared_ptr; new (&n->stats) stats_ptr(); + new (&n->logger) Logger(); + + n->logger = logging.get(fmt::format("node:{}", node_type_name(vt))); uuid_clear(n->uuid); @@ -151,6 +154,9 @@ int node_parse(struct vnode *n, json_t *json, const uuid_t sn_uuid) if (ret) return ret; + if (name_str) + n->logger = logging.get(fmt::format("node:{}", name_str)); + #ifdef __linux__ ret = json_unpack_ex(json, &err, 0, "{ s?: { s?: o, s?: i } }", "out", @@ -227,7 +233,7 @@ int node_parse(struct vnode *n, json_t *json, const uuid_t sn_uuid) if (ret) return ret; - n->cfg = json; + n->config = json; n->state = State::PARSED; return 0; @@ -262,7 +268,7 @@ int node_start(struct vnode *n) assert(n->state == State::PREPARED); assert(node_type(n)->state == State::STARTED); - info("Starting node %s", node_name_long(n)); + n->logger->info("Starting node"); ret = node_direction_start(&n->in, n); if (ret) @@ -289,7 +295,7 @@ int node_start(struct vnode *n) if (ret) throw RuntimeError("Failed to set FW mark for outgoing packets"); else - debug(LOG_SOCKET | 4, "Set FW mark for socket (sd=%u) to %u", fd, n->fwmark); + n->logger->debug("Set FW mark for socket (sd={}) to {}", fd, n->fwmark); } } #endif /* __linux__ */ @@ -307,7 +313,7 @@ int node_stop(struct vnode *n) if (n->state != State::STOPPING && n->state != State::STARTED && n->state != State::CONNECTED && n->state != State::PENDING_CONNECT) return 0; - info("Stopping node %s", node_name(n)); + n->logger->info("Stopping node"); ret = node_direction_stop(&n->in, n); if (ret) @@ -332,7 +338,7 @@ int node_pause(struct vnode *n) if (n->state != State::STARTED) return -1; - info("Pausing node %s", node_name(n)); + n->logger->info("Pausing node"); ret = node_type(n)->pause ? node_type(n)->pause(n) : 0; @@ -349,7 +355,7 @@ int node_resume(struct vnode *n) if (n->state != State::PAUSED) return -1; - info("Resuming node %s", node_name(n)); + n->logger->info("Resuming node"); ret = node_type(n)->resume ? node_type(n)->resume(n) : 0; @@ -366,7 +372,7 @@ int node_restart(struct vnode *n) if (n->state != State::STARTED) return -1; - info("Restarting node %s", node_name(n)); + n->logger->info("Restarting node"); if (node_type(n)->restart) ret = node_type(n)->restart(n); @@ -475,14 +481,14 @@ int node_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *re if (n->stats != nullptr) n->stats->update(Stats::Metric::SMPS_SKIPPED, skipped); - debug(LOG_NODE | 5, "Received %u samples from node %s of which %d have been skipped", nread, node_name(n), skipped); + n->logger->debug("Received {} samples of which {} have been skipped", nread, skipped); } else - debug(LOG_NODE | 5, "Received %u samples from node %s", nread, node_name(n)); + n->logger->debug( "Received {} samples", nread); return rread; #else - debug(LOG_NODE | 5, "Received %u samples from node %s", nread, node_name(n)); + n->logger->debug("Received {} samples", nread); return nread; #endif /* WITH_HOOKS */ @@ -518,7 +524,7 @@ int node_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *r return sent; nsent += sent; - debug(LOG_NODE | 5, "Sent %u samples to node %s", sent, node_name(n)); + n->logger->debug("Sent {} samples", sent); } return nsent; @@ -593,7 +599,7 @@ struct memory_type * node_memory_type(struct vnode *n) return node_type(n)->memory_type ? node_type(n)->memory_type(n, memory_default) : memory_default; } -int node_list_parse(struct vlist *list, json_t *cfg, struct vlist *all) +int node_list_parse(struct vlist *list, json_t *json, struct vlist *all) { struct vnode *node; const char *str; @@ -602,9 +608,11 @@ int node_list_parse(struct vlist *list, json_t *cfg, struct vlist *all) size_t index; json_t *elm; - switch (json_typeof(cfg)) { + auto logger = logging.get("node"); + + switch (json_typeof(json)) { case JSON_STRING: - str = json_string_value(cfg); + str = json_string_value(json); node = vlist_lookup_name(all, str); if (!node) goto invalid2; @@ -613,7 +621,7 @@ int node_list_parse(struct vlist *list, json_t *cfg, struct vlist *all) break; case JSON_ARRAY: - json_array_foreach(cfg, index, elm) { + json_array_foreach(json, index, elm) { if (!json_is_string(elm)) goto invalid; @@ -632,7 +640,7 @@ int node_list_parse(struct vlist *list, json_t *cfg, struct vlist *all) return 0; invalid: - error("The node list must be an a single or an array of strings referring to the keys of the 'nodes' section"); + throw RuntimeError("The node list must be an a single or an array of strings referring to the keys of the 'nodes' section"); return -1; @@ -643,7 +651,7 @@ invalid2: strcatf(&allstr, " %s", node_name_short(n)); } - error("Unknown node %s. Choose of one of: %s", str, allstr); + throw RuntimeError("Unknown node {}. Choose of one of: {}", str, allstr); return 0; } @@ -708,7 +716,7 @@ json_t * node_to_json(struct vnode *n) /* Add all additional fields of node here. * This can be used for metadata */ - json_object_update(json_node, n->cfg); + json_object_update(json_node, n->config); return json_node; } diff --git a/lib/node_direction.cpp b/lib/node_direction.cpp index 7485c8b2b..4fa51dd2d 100644 --- a/lib/node_direction.cpp +++ b/lib/node_direction.cpp @@ -94,7 +94,7 @@ int node_direction_destroy(struct vnode_direction *nd, struct vnode *n) return 0; } -int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *cfg) +int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *json) { int ret; @@ -104,9 +104,9 @@ int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *cf json_t *json_hooks = nullptr; json_t *json_signals = nullptr; - nd->cfg = cfg; + nd->config = json; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: o, s?: o, s?: i, s?: b, s?: b }", + ret = json_unpack_ex(json, &err, 0, "{ s?: o, s?: o, s?: i, s?: b, s?: b }", "hooks", &json_hooks, "signals", &json_signals, "vectorize", &nd->vectorize, @@ -114,7 +114,7 @@ int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *cf "enabled", &nd->enabled ); if (ret) - jerror(&err, "Failed to parse node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-in"); if (n->_vt->flags & (int) NodeFlags::PROVIDES_SIGNALS) { /* Do nothing.. Node-type will provide signals */ @@ -122,7 +122,7 @@ int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *cf else if (json_is_array(json_signals)) { ret = signal_list_parse(&nd->signals, json_signals); if (ret) - error("Failed to parse signal definition of node %s", node_name(n)); + throw ConfigError(json_signals, "node-config-node-signals", "Failed to parse signal definition"); } else if (json_is_string(json_signals)) { const char *dt = json_string_value(json_signals); @@ -146,7 +146,7 @@ int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *cf enum SignalType type = signal_type_from_str(type_str); if (type == SignalType::INVALID) - error("Invalid signal type %s", type_str); + throw ConfigError(json_signals, "node-config-node-signals", "Invalid signal type {}", type_str); ret = signal_list_generate(&nd->signals, count, type); if (ret) @@ -171,7 +171,7 @@ int node_direction_check(struct vnode_direction *nd, struct vnode *n) assert(n->state != State::DESTROYED); if (nd->vectorize <= 0) - error("Invalid setting 'vectorize' with value %d for node %s. Must be natural number!", nd->vectorize, node_name(n)); + throw RuntimeError("Invalid setting 'vectorize' with value {}. Must be natural number!", nd->vectorize); nd->state = State::CHECKED; diff --git a/lib/node_type.cpp b/lib/node_type.cpp index c61080617..ce92dbc59 100644 --- a/lib/node_type.cpp +++ b/lib/node_type.cpp @@ -29,6 +29,8 @@ #include #include +using namespace villas; + int node_type_start(struct vnode_type *vt, villas::node::SuperNode *sn) { int ret; @@ -36,7 +38,8 @@ int node_type_start(struct vnode_type *vt, villas::node::SuperNode *sn) if (vt->state == State::STARTED) return 0; - info("Initializing " CLR_YEL("%s") " node type which is used by %zu nodes", node_type_name(vt), vlist_length(&vt->instances)); + auto logger = logging.get(fmt::format("node:{}", node_type_name(vt))); + logger->info("Initializing node type which is used by {} nodes", vlist_length(&vt->instances)); ret = vt->type.start ? vt->type.start(sn) : 0; if (ret == 0) @@ -52,7 +55,8 @@ int node_type_stop(struct vnode_type *vt) if (vt->state != State::STARTED) return 0; - info("De-initializing " CLR_YEL("%s") " node type", node_type_name(vt)); + auto logger = logging.get(fmt::format("node:{}", node_type_name(vt))); + logger->info("De-initializing node type"); ret = vt->type.stop ? vt->type.stop() : 0; if (ret == 0) diff --git a/lib/nodes/amqp.cpp b/lib/nodes/amqp.cpp index 11de525eb..302e987e7 100644 --- a/lib/nodes/amqp.cpp +++ b/lib/nodes/amqp.cpp @@ -29,7 +29,9 @@ #include #include #include +#include +using namespace villas; using namespace villas::utils; static void amqp_default_ssl_info(struct amqp_ssl_info *s) @@ -148,7 +150,7 @@ int amqp_parse(struct vnode *n, json_t *json) "ssl", &json_ssl ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-amqp"); a->exchange = amqp_bytes_strdup(exchange); a->routing_key = amqp_bytes_strdup(routing_key); @@ -159,9 +161,8 @@ int amqp_parse(struct vnode *n, json_t *json) a->uri = strf("amqp://%s:%s@%s:%d/%s", username, password, host, port, vhost); ret = amqp_parse_url(a->uri, &a->connection_info); - if (ret != AMQP_STATUS_OK) - error("Failed to parse URI '%s' of node %s", uri, node_name(n)); + throw ConfigError(json, "node-config-node-uri", "Failed to parse URI '{}'", uri); if (json_ssl) { const char *ca_cert = nullptr; @@ -176,7 +177,7 @@ int amqp_parse(struct vnode *n, json_t *json) "client_cert", &client_cert ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json_ssl, err, "node-config-node-amqp-ssl", "Failed to parse SSL configuration"); if (ca_cert) a->ssl_info.ca_cert = strdup(ca_cert); @@ -190,7 +191,7 @@ int amqp_parse(struct vnode *n, json_t *json) a->format = format_type_lookup(format); if (!a->format) - error("Invalid format '%s' for node %s", format, node_name(n)); + throw ConfigError(json, "node-config-node-amqp-format", "Invalid format '{}'", format); return 0; } diff --git a/lib/nodes/can.cpp b/lib/nodes/can.cpp index 38e5837d8..d647c776e 100644 --- a/lib/nodes/can.cpp +++ b/lib/nodes/can.cpp @@ -40,11 +40,13 @@ #include #include #include +#include /* Forward declarations */ static struct plugin p; +using namespace villas; using namespace villas::node; using namespace villas::utils; @@ -72,8 +74,12 @@ int can_destroy(struct vnode *n) close(c->socket); free(c->sample_buf); - free(c->in); - free(c->out); + + if (c->in) + free(c->in); + + if (c->out) + free(c->out); return 0; } @@ -94,21 +100,14 @@ int can_parse_signal(json_t *json, struct vlist *node_signals, struct can_signal "can_size", &can_size, "can_offset", &can_offset ); + if (ret) + throw ConfigError(json, err, "node-config-node-can-signals"); - if (ret) { - jerror(&err, "Failed to parse signal configuration for can"); - goto out; - } + if (can_size > 8 || can_size <= 0) + throw ConfigError(json, "node-config-node-can-can-size", "can_size of {} for signal '{}' is invalid. You must satisfy 0 < can_size <= 8.", can_size, name); - if (can_size > 8 || can_size <= 0) { - error("can_size of %d for signal \"%s\" is invalid. You must satisfy 0 < can_size <= 8.", can_size, name); - goto out; - } - - if (can_offset > 8 || can_offset < 0) { - error("can_offset of %d for signal \"%s\" is invalid. You must satisfy 0 <= can_offset <= 8.", can_offset, name); - goto out; - } + if (can_offset > 8 || can_offset < 0) + throw ConfigError(json, "node-config-node-can-can-offset", "can_offset of {} for signal '{}' is invalid. You must satisfy 0 <= can_offset <= 8.", can_offset, name); sig = (struct signal*)vlist_at(node_signals, signal_index); if ((!name && !sig->name) || (name && strcmp(name, sig->name) == 0)) { @@ -119,12 +118,12 @@ int can_parse_signal(json_t *json, struct vlist *node_signals, struct can_signal goto out; } else - error("Signal configuration inconsistency detected: Signal with index %zu (\"%s\") does not match can_signal \"%s\"\n", signal_index, sig->name, name); + throw ConfigError(json, "node-config-node-can-signa;s", "Signal configuration inconsistency detected: Signal with index {} '{}' does not match can_signal '{}'", signal_index, sig->name, name); out: return ret; } -int can_parse(struct vnode *n, json_t *cfg) +int can_parse(struct vnode *n, json_t *json) { int ret = 1; struct can *c = (struct can *) n->_vd; @@ -137,7 +136,7 @@ int can_parse(struct vnode *n, json_t *cfg) c->in = nullptr; c->out = nullptr; - ret = json_unpack_ex(cfg, &err, 0, "{ s: s, s: F, s?: { s?: o }, s?: { s?: o } }", + ret = json_unpack_ex(json, &err, 0, "{ s: s, s: F, s?: { s?: o }, s?: { s?: o } }", "interface_name", &c->interface_name, "sample_rate", &c->sample_rate, "in", @@ -145,47 +144,35 @@ int can_parse(struct vnode *n, json_t *cfg) "out", "signals", &json_out_signals ); - if (ret) { - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); - goto out; - } + if (ret) + throw ConfigError(json, err, "node-config-node-can"); - if ((c->in = (struct can_signal*)calloc( + c->in = (struct can_signal*) calloc( json_array_size(json_in_signals), - sizeof(struct can_signal))) == nullptr) { - error("failed to allocate memory for input ids"); - goto out; - } - if ((c->out = (struct can_signal*)calloc( + sizeof(struct can_signal)); + if (!c->in) + throw MemoryAllocationError(); + + c->out = (struct can_signal*)calloc( json_array_size(json_out_signals), - sizeof(struct can_signal))) == nullptr) { - error("failed to allocate memory for output ids"); - goto out; - } + sizeof(struct can_signal)); + if (c->out) + throw MemoryAllocationError(); json_array_foreach(json_in_signals, i, json_signal) { - if (can_parse_signal(json_signal, &n->in.signals, c->in, i) != 0) { - error("at signal %zu in node %s.",i , node_name(n)); - goto out; - } + ret = can_parse_signal(json_signal, &n->in.signals, c->in, i); + if (ret) + throw RuntimeError("at signal {}.",i); } json_array_foreach(json_out_signals, i, json_signal) { - if (can_parse_signal(json_signal, &n->out.signals, c->out, i) != 0) { - error("at signal %zu in node %s.",i , node_name(n)); - goto out; - } + ret = can_parse_signal(json_signal, &n->out.signals, c->out, i); + if (ret) + throw RuntimeError("at signal {}.", i); } ret = 0; -out: if (ret != 0) { - free(c->in); - free(c->out); - c->in = nullptr; - c->out = nullptr; - } - return ret; } @@ -193,17 +180,15 @@ char * can_print(struct vnode *n) { struct can *c = (struct can *) n->_vd; - return strf("interface_name=%s", c->interface_name); + return strf("interface_name={}", c->interface_name); } int can_check(struct vnode *n) { struct can *c = (struct can *) n->_vd; - if (c->interface_name == nullptr || strlen(c->interface_name) == 0) { - error("interface_name is empty. Please specify the name of the CAN interface!"); - return 1; - } + if (c->interface_name == nullptr || strlen(c->interface_name) == 0) + throw RuntimeError("Empty interface_name. Please specify the name of the CAN interface!"); return 0; } @@ -226,28 +211,24 @@ int can_start(struct vnode *n) struct can *c = (struct can *) n->_vd; c->start_time = time_now(); - if ((c->socket = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { - error("Error while opening CAN socket"); - goto out; - } + c->socket = socket(PF_CAN, SOCK_RAW, CAN_RAW); + if (c->socket < 0) + throw SystemError("Error while opening CAN socket"); strcpy(ifr.ifr_name, c->interface_name); - if (ioctl(c->socket, SIOCGIFINDEX, &ifr) != 0) { - error("Could not find interface with name \"%s\".", c->interface_name); - goto out; - } + + ret = ioctl(c->socket, SIOCGIFINDEX, &ifr); + if (ret != 0) + throw SystemError("Could not find interface with name '{}'.", c->interface_name); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; - if (bind(c->socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - error("Could not bind to interface with name \"%s\" (%d).", c->interface_name, ifr.ifr_ifindex); - goto out; - } + ret = bind(c->socket, (struct sockaddr *)&addr, sizeof(addr)); + if (ret < 0) + throw SystemError("Could not bind to interface with name '{}' ({}).", c->interface_name, ifr.ifr_ifindex); - ret = 0; - -out: return ret; + return 0; } int can_stop(struct vnode *n) @@ -264,10 +245,8 @@ int can_stop(struct vnode *n) int can_conv_to_raw(union signal_data* sig, struct signal *from, void* to, int size) { - if (size <= 0 || size > 8) { - error("signal size cannot be larger than 8!"); - return 1; - } + if (size <= 0 || size > 8) + throw RuntimeError("Signal size cannot be larger than 8!"); switch(from->type) { case SignalType::BOOLEAN: @@ -327,17 +306,16 @@ int can_conv_to_raw(union signal_data* sig, struct signal *from, void* to, int s goto fail; } -fail: error("unsupported conversion to %s from raw (%p, %d)", signal_type_to_str(from->type), to, size); +fail: + throw RuntimeError("Unsupported conversion to {} from raw ({}, {})", signal_type_to_str(from->type), to, size); return 1; } int can_conv_from_raw(union signal_data* sig, void* from, int size, struct signal *to) { - if (size <= 0 || size > 8) { - error("signal size cannot be larger than 8!"); - return 1; - } + if (size <= 0 || size > 8) + throw RuntimeError("Signal size cannot be larger than 8!"); switch(to->type) { case SignalType::BOOLEAN: @@ -394,7 +372,7 @@ int can_conv_from_raw(union signal_data* sig, void* from, int size, struct signa goto fail; } fail: - error("unsupported conversion from %s to raw (%p, %d)", signal_type_to_str(to->type), from, size); + throw RuntimeError("Unsupported conversion from {} to raw ({}, {})", signal_type_to_str(to->type), from, size); return 1; } @@ -413,17 +391,13 @@ int can_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *rel assert(cnt >= 1 && smps[0]->capacity >= 1); nbytes = read(c->socket, &frame, sizeof(struct can_frame)); - if (nbytes == -1) { - error("CAN read() returned -1. Is the CAN interface up?"); - goto out; - } + if (nbytes == -1) + throw RuntimeError("CAN read() returned -1. Is the CAN interface up?"); - if ((unsigned)nbytes != sizeof(struct can_frame)) { - error("CAN read() error. read() returned %d bytes but expected %zu", nbytes, sizeof(struct can_frame)); - goto out; - } + if ((unsigned)nbytes != sizeof(struct can_frame)) + throw RuntimeError("CAN read() error. Returned {} bytes but expected {}", nbytes, sizeof(struct can_frame)); - debug(0,"received can message: (id:%d, len:%u, data: 0x%x:0x%x)", + n->logger->debug("Received can message: (id={}, len={}, data={:#x}:{:#x})", frame.can_id, frame.can_dlc, ((uint32_t*)&frame.data)[0], @@ -448,12 +422,10 @@ int can_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *rel } } - if (!found_id) { - error("did not find signal for can id %d\n", frame.can_id); - return 0; - } + if (!found_id) + throw RuntimeError("Did not find signal for can id {}", frame.can_id); - debug(0, "received %zu signals\n", c->sample_buf_num); + n->logger->debug("Received {} signals", c->sample_buf_num); /* Copy signal data to sample only when all signals have been received */ if (c->sample_buf_num == vlist_length(&n->in.signals)) { @@ -524,23 +496,19 @@ int can_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *re } for (size_t j=0; j < fsize; j++) { - debug(0,"writing can message: (id:%d, dlc:%u, data:0x%x:0x%x)", + n->logger->debug("Writing CAN message: (id={}, dlc={}, data={:#x}:{:#x})", frame[j].can_id, frame[j].can_dlc, ((uint32_t*)&frame[j].data)[0], ((uint32_t*)&frame[j].data)[1] ); - if ((nbytes = write(c->socket, &frame[j], sizeof(struct can_frame))) == -1) { - error("CAN write() returned -1. Is the CAN interface up?"); - return nwrite; - } + if ((nbytes = write(c->socket, &frame[j], sizeof(struct can_frame))) == -1) + throw RuntimeError("CAN write() returned -1. Is the CAN interface up?"); - if ((unsigned)nbytes != sizeof(struct can_frame)) { - error("CAN write() error. write() returned %d bytes but expected %zu", + if ((unsigned)nbytes != sizeof(struct can_frame)) + throw RuntimeError("CAN write() returned {} bytes but expected {}", nbytes, sizeof(struct can_frame)); - return nwrite; - } } } diff --git a/lib/nodes/comedi.cpp b/lib/nodes/comedi.cpp index 553492607..f2edfe884 100644 --- a/lib/nodes/comedi.cpp +++ b/lib/nodes/comedi.cpp @@ -37,9 +37,9 @@ using namespace villas::utils; /* Utility functions to dump a comedi_cmd graciously taken from comedilib demo */ static char* comedi_cmd_trigger_src(unsigned int src, char *buf); -static void comedi_dump_cmd(comedi_cmd *cmd, int debug_level); +static void comedi_dump_cmd(Logger logger, comedi_cmd *cmd); -static int comedi_parse_direction(struct comedi *c, struct comedi_direction *d, json_t *cfg) +static int comedi_parse_direction(struct comedi *c, struct comedi_direction *d, json_t *json) { int ret; @@ -50,14 +50,14 @@ static int comedi_parse_direction(struct comedi *c, struct comedi_direction *d, d->subdevice = -1; d->buffer_size = 16; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: i, s?: i, s: o, s: i }", + ret = json_unpack_ex(json, &err, 0, "{ s?: i, s?: i, s: o, s: i }", "subdevice", &d->subdevice, "bufsize", &d->buffer_size, "signals", &json_chans, "rate", &d->sample_rate_hz ); if (ret) - jerror(&err, "Failed to parse configuration"); + throw ConfigError(json, err, "node-config-node-comedi"); if (!json_is_array(json_chans)) return -1; @@ -69,10 +69,8 @@ static int comedi_parse_direction(struct comedi *c, struct comedi_direction *d, json_t *json_chan; d->chanlist_len = json_array_size(json_chans); - if (d->chanlist_len == 0) { - error("No channels configured"); - return 0; - } + if (d->chanlist_len == 0) + throw ConfigError(json_chans, "node-config-node-channels", "No channels configured"); d->chanlist = new unsigned int[d->chanlist_len]; if (!d->chanlist) @@ -85,14 +83,15 @@ static int comedi_parse_direction(struct comedi *c, struct comedi_direction *d, json_array_foreach(json_chans, i, json_chan) { int num, range, aref; ret = json_unpack_ex(json_chan, &err, 0, "{ s: i, s: i, s: i }", - "channel", &num, - "range", &range, - "aref", &aref); + "channel", &num, + "range", &range, + "aref", &aref + ); if (ret) - jerror(&err, "Failed to parse configuration"); + throw ConfigError(json_chan, err, "node-config-node-comedi"); if (aref < AREF_GROUND || aref > AREF_OTHER) - error("Invalid value for analog reference: aref=%d", aref); + throw ConfigError(json_chan, "node-config-node-comedi-aref", "Invalid value for analog reference: aref={}", aref); d->chanlist[i] = CR_PACK(num, range, aref); } @@ -121,25 +120,22 @@ static int comedi_start_common(struct vnode *n) ret = comedi_get_n_ranges(c->dev, d->subdevice, channel); if (ret < 0) - error("Failed to get ranges for channel %d on subdevice %d", - channel, d->subdevice); + throw RuntimeError("Failed to get ranges for channel {} on subdevice {}", channel, d->subdevice); if (range >= ret) - error("Invalid range for channel %d on subdevice %d: range=%d", - channel, d->subdevice, range); + throw RuntimeError("Invalid range for channel {} on subdevice {}: range={}", channel, d->subdevice, range); ret = comedi_get_maxdata(c->dev, d->subdevice, channel); if (ret <= 0) - error("Failed to get max. data value for channel %d on subdevice %d", - channel, d->subdevice); + throw RuntimeError("Failed to get max. data value for channel {} on subdevice {}", channel, d->subdevice); d->chanspecs[i].maxdata = ret; d->chanspecs[i].range = comedi_get_range(c->dev, d->subdevice, channel, range); - info("%s channel: %d aref=%d range=%d maxdata=%d", - (d == &c->in ? "Input" : "Output"), channel, - CR_AREF(d->chanlist[i]), range, d->chanspecs[i].maxdata); + n->logger->info("{} channel: {} aref={} range={} maxdata={}", + (d == &c->in ? "Input" : "Output"), channel, + CR_AREF(d->chanlist[i]), range, d->chanspecs[i].maxdata); } const int flags = comedi_get_subdevice_flags(c->dev, d->subdevice); @@ -150,13 +146,13 @@ static int comedi_start_common(struct vnode *n) comedi_set_max_buffer_size(c->dev, d->subdevice, d->buffer_size); ret = comedi_get_buffer_size(c->dev, d->subdevice); if (ret != d->buffer_size) - error("Failed to set buffer size for subdevice %d of node '%s'", d->subdevice, node_name(n)); + throw RuntimeError("Failed to set buffer size for subdevice {}", d->subdevice); - info("Set buffer size for subdevice %d to %d bytes", d->subdevice, d->buffer_size); + n->logger->info("Set buffer size for subdevice {} to {} bytes", d->subdevice, d->buffer_size); ret = comedi_lock(c->dev, d->subdevice); if (ret) - error("Failed to lock subdevice %d for node '%s'", d->subdevice, node_name(n)); + throw RuntimeError("Failed to lock subdevice {}", d->subdevice); } return 0; @@ -172,24 +168,23 @@ static int comedi_start_in(struct vnode *n) if (d->subdevice < 0) { d->subdevice = comedi_find_subdevice_by_type(c->dev, COMEDI_SUBD_AI, 0); if (d->subdevice < 0) - error("Cannot find analog input device for node '%s'", node_name(n)); + throw RuntimeError("Cannot find analog input device for node '{}'"); } else { /* Check if subdevice is usable */ ret = comedi_get_subdevice_type(c->dev, d->subdevice); if (ret != COMEDI_SUBD_AI) - error("Input subdevice of node '%s' is not an analog input", node_name(n)); + throw RuntimeError("Input subdevice is not an analog input"); } ret = comedi_get_subdevice_flags(c->dev, d->subdevice); if (ret < 0 || !(ret & SDF_CMD_READ)) - error("Input subdevice of node '%s' does not support 'read' commands", node_name(n)); + throw RuntimeError("Input subdevice does not support 'read' commands"); comedi_set_read_subdevice(c->dev, d->subdevice); ret = comedi_get_read_subdevice(c->dev); if (ret < 0 || ret != d->subdevice) - error("Failed to change 'read' subdevice from %d to %d of node '%s'", - ret, d->subdevice, node_name(n)); + throw RuntimeError("Failed to change 'read' subdevice from {} to {}", ret, d->subdevice); comedi_cmd cmd; memset(&cmd, 0, sizeof(cmd)); @@ -225,14 +220,14 @@ static int comedi_start_in(struct vnode *n) ret = comedi_command_test(c->dev, &cmd); ret = comedi_command_test(c->dev, &cmd); if (ret < 0) - error("Invalid command for input subdevice of node '%s'", node_name(n)); + throw RuntimeError("Invalid command for input subdevice"); - info("Input command:"); - comedi_dump_cmd(&cmd, 1); + n->logger->info("Input command:"); + comedi_dump_cmd(n->logger, &cmd); ret = comedi_command(c->dev, &cmd); if (ret < 0) - error("Failed to issue command to input subdevice of node '%s'", node_name(n)); + throw RuntimeError("Failed to issue command to input subdevice"); d->started = time_now(); d->counter = 0; @@ -245,9 +240,9 @@ static int comedi_start_in(struct vnode *n) if (!c->buf) throw MemoryAllocationError(); - info("Compiled for kernel read() interface"); + n->logger->info("Compiled for kernel read() interface"); #else - info("Compiled for kernel mmap() interface"); + n->logger->info("Compiled for kernel mmap() interface"); #endif return 0; @@ -263,23 +258,22 @@ static int comedi_start_out(struct vnode *n) if (d->subdevice < 0) { d->subdevice = comedi_find_subdevice_by_type(c->dev, COMEDI_SUBD_AO, 0); if (d->subdevice < 0) - error("Cannot find analog output device for node '%s'", node_name(n)); + throw RuntimeError("Cannot find analog output device"); } else { ret = comedi_get_subdevice_type(c->dev, d->subdevice); if (ret != COMEDI_SUBD_AO) - error("Output subdevice of node '%s' is not an analog output", node_name(n)); + throw RuntimeError("Output subdevice is not an analog output"); } ret = comedi_get_subdevice_flags(c->dev, d->subdevice); if (ret < 0 || !(ret & SDF_CMD_WRITE)) - error("Output subdevice of node '%s' does not support 'write' commands", node_name(n)); + throw RuntimeError("Output subdevice does not support 'write' commands"); comedi_set_write_subdevice(c->dev, d->subdevice); ret = comedi_get_write_subdevice(c->dev); if (ret < 0 || ret != d->subdevice) - error("Failed to change 'write' subdevice from %d to %d of node '%s'", - ret, d->subdevice, node_name(n)); + throw RuntimeError("Failed to change 'write' subdevice from {} to {}", ret, d->subdevice); comedi_cmd cmd; memset(&cmd, 0, sizeof(cmd)); @@ -311,24 +305,24 @@ static int comedi_start_out(struct vnode *n) /* First run might change command, second should return successfully */ ret = comedi_command_test(c->dev, &cmd); if (ret < 0) - error("Invalid command for input subdevice of node '%s'", node_name(n)); + throw RuntimeError("Invalid command for input subdevice"); ret = comedi_command_test(c->dev, &cmd); if (ret < 0) - error("Invalid command for input subdevice of node '%s'", node_name(n)); + throw RuntimeError("Invalid command for input subdevice"); - info("Output command:"); - comedi_dump_cmd(&cmd, 1); + n->logger->info("Output command:"); + comedi_dump_cmd(n->logger, &cmd); ret = comedi_command(c->dev, &cmd); if (ret < 0) - error("Failed to issue command to input subdevice of node '%s'", node_name(n)); + throw RuntimeError("Failed to issue command to input subdevice of node '{}'"); /* Output will only start after the internal trigger */ d->running = false; d->last_debug = time_now(); - /* Allocate buffer for one complete villas sample */ + /* Allocate buffer for one complete VILLAS sample */ /** @todo: maybe increase buffer size according to c->vectorize */ const size_t local_buffer_size = d->sample_size * d->chanlist_len; d->buffer = new char[local_buffer_size]; @@ -352,13 +346,13 @@ static int comedi_start_out(struct vnode *n) for (unsigned i = 0; i < d->buffer_size / local_buffer_size; i++) { size_t written = write(comedi_fileno(c->dev), d->buffer, local_buffer_size); if (written != local_buffer_size) { - error("Cannot preload Comedi buffer"); + throw RuntimeError("Cannot preload Comedi buffer"); } } const size_t villas_samples_in_kernel_buf = d->buffer_size / (d->sample_size * d->chanlist_len); - const double latencyMs = (double)villas_samples_in_kernel_buf / d->sample_rate_hz * 1e3; - info("Added latency due to buffering: %4.1f ms\n", latencyMs); + const double latencyMs = (double) villas_samples_in_kernel_buf / d->sample_rate_hz * 1e3; + n->logger->info("Added latency due to buffering: {:4.1f} ms", latencyMs); return 0; } @@ -373,7 +367,7 @@ static int comedi_stop_in(struct vnode *n) ret = comedi_unlock(c->dev, d->subdevice); if (ret) - error("Failed to lock subdevice %d for node '%s'", d->subdevice, node_name(n)); + throw RuntimeError("Failed to lock subdevice {}", d->subdevice); return 0; } @@ -388,12 +382,12 @@ static int comedi_stop_out(struct vnode *n) ret = comedi_unlock(c->dev, d->subdevice); if (ret) - error("Failed to lock subdevice %d for node '%s'", d->subdevice, node_name(n)); + throw RuntimeError("Failed to lock subdevice {}", d->subdevice); return 0; } -int comedi_parse(struct vnode *n, json_t *cfg) +int comedi_parse(struct vnode *n, json_t *json) { int ret; struct comedi *c = (struct comedi *) n->_vd; @@ -404,13 +398,13 @@ int comedi_parse(struct vnode *n, json_t *cfg) json_t *json_out = nullptr; json_error_t err; - ret = json_unpack_ex(cfg, &err, 0, "{ s: s, s?: o, s?: o }", - "device", &device, - "in", &json_in, - "out", &json_out); + ret = json_unpack_ex(json, &err, 0, "{ s: s, s?: o, s?: o }", + "device", &device, + "in", &json_in, + "out", &json_out); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-comedi"); c->in.present = json_in != nullptr; c->in.enabled = false; @@ -456,15 +450,13 @@ int comedi_start(struct vnode *n) struct comedi *c = (struct comedi *) n->_vd; c->dev = comedi_open(c->device); - if (!c->dev) { - const char *err = comedi_strerror(comedi_errno()); - error("Failed to open device: %s", err); - } + if (!c->dev) + throw RuntimeError("Failed to open device: {}", comedi_strerror(comedi_errno())); /* Enable non-blocking syscalls */ /** @todo: verify if this works with both input and output, so comment out */ //if (fcntl(comedi_fileno(c->dev), F_SETFL, O_NONBLOCK)) - // error("Failed to set non-blocking flag in Comedi FD of node '%s'", node_name(n)); + // throw RuntimeError("Failed to set non-blocking flag in Comedi FD"); comedi_start_common(n); @@ -485,10 +477,10 @@ int comedi_start(struct vnode *n) } #if !COMEDI_USE_READ - info("Mapping Comedi buffer of %d bytes", c->in.buffer_size); + n->logger->info("Mapping Comedi buffer of {} bytes", c->in.buffer_size); c->map = mmap(nullptr, c->in.buffer_size, PROT_READ, MAP_SHARED, comedi_fileno(c->dev), 0); if (c->map == MAP_FAILED) - error("Failed to map comedi buffer of node '%s'", node_name(n)); + throw RuntimeError("Failed to map Comedi buffer"); c->front = 0; c->back = 0; @@ -528,9 +520,9 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * ret = comedi_get_buffer_contents(c->dev, d->subdevice); if (ret < 0) { if (comedi_errno() == EBUF_OVR) - error("Comedi buffer overflow"); + throw RuntimeError("Comedi buffer overflow"); else - error("Comedi error: %s", comedi_strerror(comedi_errno())); + throw RuntimeError("Comedi error: {}", comedi_strerror(comedi_errno())); } fd_set rdset; @@ -543,7 +535,7 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * ret = select(comedi_fileno(c->dev) + 1, &rdset, nullptr, nullptr, &timeout); if (ret < 0) - error("select"); + throw RuntimeError("Failed select()"); else if (ret == 0) /* hit timeout */ return 0; else if (FD_ISSET(comedi_fileno(c->dev), &rdset)) { /* comedi file descriptor became ready */ @@ -553,12 +545,12 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * ret = read(comedi_fileno(c->dev), c->bufptr, MIN(bytes_requested, buffer_bytes_free)); if (ret < 0) { if (errno == EAGAIN) - error("read"); + throw RuntimeError("Failed read()"); else return 0; } else if (ret == 0) { - warning("select timeout, no samples available"); + n->logger->warn("Timeout in select(), no samples available"); return 0; } else { @@ -567,11 +559,8 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * const size_t raw_samples_available = bytes_available / d->sample_size; const size_t villas_samples_available = raw_samples_available / d->chanlist_len; - info("there are %zd bytes available (%zu requested) => %zu villas samples", - bytes_available, bytes_requested, villas_samples_available); - - info("there are %zu kB available (%zu kB requested)", - bytes_available / 1024, bytes_requested / 1024); + n->logger->info("There are {} bytes available ({} requested) => {} VILLAS samples", + bytes_available, bytes_requested, villas_samples_available); if (cnt > villas_samples_available) cnt = villas_samples_available; @@ -588,10 +577,8 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * smps[i]->length = d->chanlist_len; - if (smps[i]->capacity < d->chanlist_len) { - error("Sample has insufficient capacity: %d < %zd", - smps[i]->capacity, d->chanlist_len); - } + if (smps[i]->capacity < d->chanlist_len) + throw RuntimeError("Sample has insufficient capacity: {} < {}", smps[i]->capacity, d->chanlist_len); for (unsigned si = 0; si < d->chanlist_len; si++) { unsigned int raw; @@ -606,7 +593,7 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * smps[i]->data[si].f = comedi_to_phys(raw, d->chanspecs[si].range, d->chanspecs[si].maxdata); if (std::isnan(smps[i]->data[si].f)) - warning("Input: channel %d clipped", CR_CHAN(d->chanlist[si])); + n->logger->warn("Input: channel {} clipped", CR_CHAN(d->chanlist[si])); } } @@ -618,7 +605,7 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * memmove(c->buf, c->bufptr, bytes_left); } - info("consumed %zd bytes", bytes_consumed); + n->logger->info("Consumed {} bytes", bytes_consumed); /* Start at the beginning again */ c->bufptr = c->buf; @@ -626,10 +613,9 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * return cnt; } } - else { + else /* unknown file descriptor became ready */ - printf("unknown file descriptor ready\n"); - } + n->logger->warn("Unknown file descriptor ready"); return -1; } @@ -646,16 +632,16 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * comedi_set_read_subdevice(c->dev, d->subdevice); - info("current bufpos=%ld", c->bufpos); + n->logger->info("Current bufpos={}", c->bufpos); #if 0 if (c->bufpos > (d->buffer_size - villas_sample_size)) { ret = comedi_get_buffer_read_offset(c->dev, d->subdevice); if (ret < 0) - error("Canot get offset"); + throw RuntimeError("Canot get offset"); c->bufpos = ret; - info("change bufpos=%ld", c->bufpos); + n->logger->info("Change bufpos={}", c->bufpos); } #endif @@ -664,9 +650,9 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * return 0; else if (ret < 0) { if (comedi_errno() == EBUF_OVR) - error("Comedi buffer overflow"); + throw RuntimeError("Comedi buffer overflow"); else - error("Comedi error: %s", comedi_strerror(comedi_errno())); + throw RuntimeError("Comedi error: {}", comedi_strerror(comedi_errno())); } const size_t bytes_available = ret; @@ -675,17 +661,17 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * if (villas_sample_count == 0) return 0; - info("there are %ld villas samples (%ld raw bytes, %ld channels)", villas_sample_count, bytes_available, d->chanlist_len); + n->logger->info("There are {} VILLAS samples ({} raw bytes, {} channels)", villas_sample_count, bytes_available, d->chanlist_len); #if 0 if (villas_sample_count == 1) - info("front=%ld back=%ld bufpos=%ld", c->front, c->back, c->bufpos); + n->logger->info("front={} back={} bufpos={}", c->front, c->back, c->bufpos); if ((c->bufpos + bytes_available) >= d->buffer_size) { /* Let comedi do the wraparound, only consume until end of buffer */ villas_sample_count = (d->buffer_size - c->bufpos) / villas_sample_size; - warning("Reducing consumption from %d to %ld bytes", ret, bytes_available); - warning("Only consume %ld villas samples b/c of buffer wraparound", villas_sample_count); + n->logger->warn("Reducing consumption from {} to {} bytes", ret, bytes_available); + n->logger->warn("Only consume {} VILLAS samples b/c of buffer wraparound", villas_sample_count); } #endif @@ -694,12 +680,11 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * #if 0 if (bytes_available != 0 && bytes_available < villas_sample_size) { - warning("Cannot consume samples, only %d bytes available, throw away", ret); + n->logger->warn("Cannot consume samples, only {} bytes available, throw away", ret); ret = comedi_mark_buffer_read(c->dev, d->subdevice, bytes_available); if (ret != bytes_available) - error("Cannot throw away %ld bytes, returned %d, wtf comedi?!", - bytes_available, ret); + throw RuntimeError("Cannot throw away {} bytes, returned {}", bytes_available, ret); return 0; } @@ -709,15 +694,15 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * ret = comedi_mark_buffer_read(c->dev, d->subdevice, samples_total_bytes); if (ret == 0) { - warning("Marking read buffer (%ld bytes) not working, try again later", samples_total_bytes); + n->logger->warn("Marking read buffer ({} bytes) not working, try again later", samples_total_bytes); return 0; } else if (ret != samples_total_bytes) { - warning("Can only mark %d bytes as read, reducing samples", ret); + n->logger->warn("Can only mark {} bytes as read, reducing samples", ret); return 0; } else - info("Consume %d bytes", ret); + n->logger->info("Consume {} bytes", ret); /* Align front to whole samples */ c->front = c->back + samples_total_bytes; @@ -734,8 +719,7 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * smps[i]->length = d->chanlist_len; if (smps[i]->capacity < d->chanlist_len) - error("Sample has insufficient capacity: %d < %ld", - smps[i]->capacity, d->chanlist_len); + throw RuntimeError("Sample has insufficient capacity: {} < {}", smps[i]->capacity, d->chanlist_len); for (int si = 0; si < d->chanlist_len; si++) { unsigned int raw; @@ -747,15 +731,14 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * smps[i]->data[si].f = comedi_to_phys(raw, d->chanspecs[si].range, d->chanspecs[si].maxdata); - if (isnan(smps[i]->data[si].f)) { - error("got nan"); - } + if (isnan(smps[i]->data[si].f)) + throw RuntimeError("Got nan"); // smps[i]->data[si].i = raw; c->bufpos += d->sample_size; if (c->bufpos >= d->buffer_size) { - warning("read buffer wraparound"); + n->logger->warn("Read buffer wraparound"); // c->bufpos = 0; } } @@ -763,52 +746,52 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * // const size_t bytes_consumed = c->front - c->back; -// info("advance comedi buffer by %ld bytes", bytes_consumed); +// n->logger->info("Advance Comedi buffer by {} bytes", bytes_consumed); ret = comedi_get_buffer_read_offset(c->dev, d->subdevice); if (ret < 0) { if (comedi_errno() != EPIPE) - error("Failed to get read buffer offset: %d, comedi errno %d", ret, comedi_errno()); + throw RuntimeError("Failed to get read buffer offset: {}, Comedi error {}", ret, comedi_strerror(comedi_errno())); else ret = c->bufpos; } - warning("change bufpos: %ld to %d", c->bufpos, ret); + n->logger->warn("Change bufpos: {} to {}", c->bufpos, ret); c->bufpos = ret; #if 0 ret = comedi_mark_buffer_read(c->dev, d->subdevice, bytes_consumed); if (ret < 0) //!= bytes_consumed) - error("Failed to mark buffer position (ret=%d) for input stream of node '%s'", ret, node_name(n)); + throw RuntimeError("Failed to mark buffer position (ret={}) for input stream", ret); // else if (ret == 0) { else { - info("consumed %ld bytes", bytes_consumed); - info("mark buffer returned %d", ret); + n->logger->info("Consumed {} bytes", bytes_consumed); + n->logger->info("Mark buffer returned {}", ret); if (ret == 0) { ret = comedi_mark_buffer_read(c->dev, d->subdevice, bytes_consumed); - info("trying again, mark buffer returned now %d", ret); + n->logger->info("Trying again, mark buffer returned now {}", ret); } if (ret > 0) { ret = comedi_get_buffer_read_offset(c->dev, d->subdevice); if (ret < 0) - error("Failed to get read buffer offset"); + throw RuntimeError("Failed to get read buffer offset"); - warning("change bufpos1: %ld to %d", c->bufpos, ret); + n->logger->warn("Change bufpos1: {} to {}", c->bufpos, ret); c->bufpos = ret; } else { -// warning("change bufpos2: %ld to %ld", c->bufpos, c->); +// n->logger->warn("Change bufpos2: {} to {}", c->bufpos, c->); // c->bufpos += bytes_consumed; - warning("keep bufpos=%ld", c->bufpos); + n->logger->warn("Keep bufpos={}", c->bufpos); } // c->bufpos = 0; } #endif -// info("new bufpos: %ld", c->bufpos); +// n->logger->info("New bufpos: {}", c->bufpos); c->back = c->front; @@ -824,7 +807,7 @@ int comedi_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned struct comedi_direction *d = &c->out; if (!d->enabled) { - warning("Attempting to write, but output is not enabled"); + n->logger->warn("Attempting to write, but output is not enabled"); return 0; } @@ -832,13 +815,13 @@ int comedi_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned /* Output was not yet running, so start now */ ret = comedi_internal_trigger(c->dev, d->subdevice, 0); if (ret < 0) - error("Failed to trigger-start output"); + throw RuntimeError("Failed to trigger-start output"); d->started = time_now(); d->counter = 0; d->running = true; - info("Starting output of node '%s'", node_name(n)); + n->logger->info("Starting output"); } const size_t buffer_capacity_raw = d->buffer_size / d->sample_size; @@ -848,9 +831,9 @@ int comedi_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned ret = comedi_get_buffer_contents(c->dev, d->subdevice); if (ret < 0) { if (comedi_errno() == EBUF_OVR) - error("Comedi buffer overflow"); + throw RuntimeError("Comedi buffer overflow"); else - error("Comedi error: %s", comedi_strerror(comedi_errno())); + throw RuntimeError("Comedi error: {}", comedi_strerror(comedi_errno())); } const size_t bytes_in_buffer = ret; @@ -858,15 +841,15 @@ int comedi_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned const size_t villas_samples_in_buffer = raw_samples_in_buffer / d->chanlist_len; if (villas_samples_in_buffer == buffer_capacity_villas) { - warning("Comedi buffer is full"); + n->logger->warn("Comedi buffer is full"); return 0; } else { struct timespec now = time_now(); if (time_delta(&d->last_debug, &now) >= 1) { - debug(LOG_COMEDI | 2, "Comedi write buffer: %4zd villas samples (%2.0f%% of buffer)", - villas_samples_in_buffer, - (100.0f * villas_samples_in_buffer / buffer_capacity_villas)); + n->logger->debug("Comedi write buffer: {} VILLAS samples ({}% of buffer)", + villas_samples_in_buffer, + (100.0f * villas_samples_in_buffer / buffer_capacity_villas)); d->last_debug = time_now(); } @@ -877,8 +860,7 @@ int comedi_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned while (villas_samples_written < cnt) { struct sample *sample = smps[villas_samples_written]; if (sample->length != d->chanlist_len) - error("Value count in sample (%d) != configured output channels (%zd)", - sample->length, d->chanlist_len); + throw RuntimeError("Value count in sample ({}) != configured output channels ({})", sample->length, d->chanlist_len); d->bufptr = d->buffer; @@ -921,18 +903,17 @@ int comedi_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned /* Try to write one complete villas sample to comedi */ size_t written = write(comedi_fileno(c->dev), d->buffer, villas_sample_size); if (written < 0) - error("write"); + throw RuntimeError("write() failed"); else if (written == 0) break; /* Comedi doesn't accept any more samples at the moment */ else if (written == villas_sample_size) villas_samples_written++; else - error("Only partial sample written (%zu bytes), oops", written); + throw RuntimeError("Only partial sample written ({} bytes), oops", written); } - if (villas_samples_written == 0) { - warning("Nothing done"); - } + if (villas_samples_written == 0) + n->logger->warn("Nothing done"); d->counter += villas_samples_written; @@ -960,27 +941,27 @@ char* comedi_cmd_trigger_src(unsigned int src, char *buf) return buf; } -void comedi_dump_cmd(comedi_cmd *cmd, int debug_level) +void comedi_dump_cmd(Logger logger, comedi_cmd *cmd) { char buf[256]; char* src; - debug(LOG_COMEDI | debug_level, "subdevice: %u", cmd->subdev); + logger->debug("subdevice: {}", cmd->subdev); src = comedi_cmd_trigger_src(cmd->start_src, buf); - debug(LOG_COMEDI | debug_level, "start: %-8s %u", src, cmd->start_arg); + logger->debug("start: {:-8s} {}", src, cmd->start_arg); src = comedi_cmd_trigger_src(cmd->scan_begin_src, buf); - debug(LOG_COMEDI | debug_level, "scan_begin: %-8s %u", src, cmd->scan_begin_arg); + logger->debug("scan_begin: {:-8s} {}", src, cmd->scan_begin_arg); src = comedi_cmd_trigger_src(cmd->convert_src, buf); - debug(LOG_COMEDI | debug_level, "convert: %-8s %u", src, cmd->convert_arg); + logger->debug("convert: {:-8s} {}", src, cmd->convert_arg); src = comedi_cmd_trigger_src(cmd->scan_end_src, buf); - debug(LOG_COMEDI | debug_level, "scan_end: %-8s %u", src, cmd->scan_end_arg); + logger->debug("scan_end: {:-8s} {}", src, cmd->scan_end_arg); src = comedi_cmd_trigger_src(cmd->stop_src,buf); - debug(LOG_COMEDI | debug_level, "stop: %-8s %u", src, cmd->stop_arg); + logger->debug("stop: {:-8s} {}", src, cmd->stop_arg); } int comedi_poll_fds(struct vnode *n, int fds[]) diff --git a/lib/nodes/ethercat.cpp b/lib/nodes/ethercat.cpp index 10e560d8e..08cd888dc 100644 --- a/lib/nodes/ethercat.cpp +++ b/lib/nodes/ethercat.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -75,7 +74,7 @@ static void ethercat_cyclic_task(struct vnode *n) /* Receive process data */ smp = sample_alloc(&w->pool); if (!smp) { - warning("Pool underrun in node %s", node_name(n)); + n->logger->warn("Pool underrun"); continue; } @@ -92,7 +91,7 @@ static void ethercat_cyclic_task(struct vnode *n) ret = queue_signalled_push(&w->queue, smp); if (ret) - warning("Ethercat: Failed to enqueue samples"); + n->logger->warn("Failed to enqueue samples"); /* Write process data */ smp = w->send.exchange(nullptr); @@ -116,9 +115,9 @@ int ethercat_type_start(villas::node::SuperNode *sn) int ret; json_error_t err; - json_t *cfg = sn->getConfig(); - if (cfg) { - ret = json_unpack_ex(cfg, &err, 0, "{ s?: i, s?:i, s?: { s?: { s?: i, s?: i, s?: i } } }", + json_t *json = sn->getConfig(); + if (json) { + ret = json_unpack_ex(json, &err, 0, "{ s?: i, s?:i, s?: { s?: { s?: i, s?: i, s?: i } } }", "ethernet", "master", &master_id, "alias", &alias, @@ -128,7 +127,7 @@ int ethercat_type_start(villas::node::SuperNode *sn) "vendor_id", &coupler.vendor_id ); if (ret) - jerror(&err, "Failed to parse EtherCAT configuration"); + throw ConfigError(json, err, "node-config-node-ethercat"); } master = ecrt_request_master(master_id); @@ -145,21 +144,23 @@ int ethercat_type_start(villas::node::SuperNode *sn) int ethercat_type_stop() { - info("Releasing EtherCAT master"); + auto logger = logging.get("node:ethercat"); + + logger->info("Releasing EtherCAT master"); ecrt_release_master(master); return 0; } -int ethercat_parse(struct vnode *n, json_t *cfg) +int ethercat_parse(struct vnode *n, json_t *json) { struct ethercat *w = (struct ethercat *) n->_vd; int ret; json_error_t err; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: F, s?: { s: i, s?: F, s?: i, s?: i, s?: i }, s?: { s: i, s?: F, s?: i, s?: i, s?: i } }", + ret = json_unpack_ex(json, &err, 0, "{ s?: F, s?: { s: i, s?: F, s?: i, s?: i, s?: i }, s?: { s: i, s?: F, s?: i, s?: i, s?: i } }", "rate", &w->rate, "out", "num_channels", &w->out.num_channels, @@ -175,7 +176,7 @@ int ethercat_parse(struct vnode *n, json_t *cfg) "vendor_id", &w->in.vendor_id ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-ethercat"); return 0; } @@ -272,35 +273,25 @@ int ethercat_start(struct vnode *n) /* Configure analog in */ w->in.sc = ecrt_master_slave_config(master, alias, w->in.position, w->in.vendor_id, w->in.product_code); - if (!w->in.sc) { - warning("Failed to get slave configuration."); - return -1; - } + if (!w->in.sc) + throw RuntimeError("Failed to get slave configuration."); ret = ecrt_slave_config_pdos(w->in.sc, EC_END, slave_4_syncs); - if (ret) { - error("Failed to configure PDOs."); - return -1; - } + if (ret) + throw RuntimeError("Failed to configure PDOs."); /* Configure analog out */ w->out.sc = ecrt_master_slave_config(master, alias, w->out.position, w->out.vendor_id, w->out.product_code); - if (!w->out.sc) { - warning("Failed to get slave configuration."); - return -1; - } + if (!w->out.sc) + throw RuntimeError("Failed to get slave configuration."); ret = ecrt_slave_config_pdos(w->out.sc, EC_END, slave_3_syncs); - if (ret) { - warning("Failed to configure PDOs."); - return -1; - } + if (ret) + throw RuntimeError("Failed to configure PDOs."); ret = ecrt_domain_reg_pdo_entry_list(w->domain, w->domain_regs); - if (ret) { - error("PDO entry registration failed!"); - return -1; - } + if (ret) + throw RuntimeError("PDO entry registration failed!"); /** @todo Check that master is not already active... */ ret = ecrt_master_activate(master); @@ -338,7 +329,7 @@ int ethercat_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned avail = queue_signalled_pull_many(&w->queue, (void **) cpys, cnt); if (avail < 0) - warning("Pool underrun for node %s: avail=%u", node_name(n), avail); + n->logger->warn("Pool underrun: avail={}", avail); sample_copy_many(smps, cpys, avail); sample_decref_many(cpys, avail); diff --git a/lib/nodes/example.cpp b/lib/nodes/example.cpp index 108c61b88..d8ba59850 100644 --- a/lib/nodes/example.cpp +++ b/lib/nodes/example.cpp @@ -24,11 +24,14 @@ #include #include #include +#include #include +#include /* Forward declartions */ static struct plugin p; +using namespace villas; using namespace villas::node; using namespace villas::utils; @@ -70,7 +73,7 @@ int example_destroy(struct vnode *n) return 0; } -int example_parse(struct vnode *n, json_t *cfg) +int example_parse(struct vnode *n, json_t *json) { int ret; struct example *s = (struct example *) n->_vd; @@ -79,12 +82,12 @@ int example_parse(struct vnode *n, json_t *cfg) /* TODO: Add implementation here. The following is just an example */ - ret = json_unpack_ex(cfg, &err, 0, "{ s?: i, s?: s }", + ret = json_unpack_ex(json, &err, 0, "{ s?: i, s?: s }", "setting1", &s->setting1, "setting2", &s->setting2 ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-example"); return 0; } diff --git a/lib/nodes/exec.cpp b/lib/nodes/exec.cpp index e7bfc662a..cafd7c363 100644 --- a/lib/nodes/exec.cpp +++ b/lib/nodes/exec.cpp @@ -31,7 +31,7 @@ using namespace villas; using namespace villas::utils; -int exec_parse(struct vnode *n, json_t *cfg) +int exec_parse(struct vnode *n, json_t *json) { struct exec *e = (struct exec *) n->_vd; @@ -45,7 +45,7 @@ int exec_parse(struct vnode *n, json_t *cfg) const char *format = "villas.human"; int shell = -1; - ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s?: s, s?: b, s?: o, s?: b, s?: s }", + ret = json_unpack_ex(json, &err, 0, "{ s: o, s?: s, s?: b, s?: o, s?: b, s?: s }", "exec", &json_exec, "format", &format, "flush", &flush, @@ -54,7 +54,7 @@ int exec_parse(struct vnode *n, json_t *cfg) "working_directory", &wd ); if (ret) - throw ConfigError(cfg, err, "node-config-node-exec"); + throw ConfigError(json, err, "node-config-node-exec"); e->flush = flush; e->shell = shell < 0 ? json_is_string(json_exec) : shell; @@ -101,16 +101,13 @@ int exec_parse(struct vnode *n, json_t *cfg) } } + json_t *json_format = json_object_get(json, "format"); e->format = format_type_lookup(format); - if (!e->format) { - json_t *json_format = json_object_get(cfg, "format"); + if (!e->format) throw ConfigError(json_format, "node-config-node-exec-format", "Invalid format: {)", format); - } - if (!(e->format->flags & (int) IOFlags::NEWLINES)) { - json_t *json_format = json_object_get(cfg, "format"); + if (!(e->format->flags & (int) IOFlags::NEWLINES)) throw ConfigError(json_format, "node-config-node-exec-format", "Only line-delimited formats are currently supported"); - } return 0; } @@ -127,7 +124,7 @@ int exec_prepare(struct vnode *n) /* Start subprocess */ e->proc = std::make_unique(e->command, e->arguments, e->environment, e->working_dir, e->shell); - debug(2, "Started sub-process with pid=%d", e->proc->getPid()); + n->logger->debug("Started sub-process with pid={}", e->proc->getPid()); return 0; } @@ -170,22 +167,15 @@ int exec_destroy(struct vnode *n) return 0; } -int exec_start(struct vnode *n) -{ -// struct exec *e = (struct exec *) n->_vd; - - return 0; -} - int exec_stop(struct vnode *n) { struct exec *e = (struct exec *) n->_vd; /* Stop subprocess */ - debug(2, "Killing sub-process with pid=%d", e->proc->getPid()); + n->logger->debug("Killing sub-process with pid={}", e->proc->getPid()); e->proc->kill(SIGINT); - debug(2, "Waiting for sub-process with pid=%d to terminate", e->proc->getPid()); + n->logger->debug("Waiting for sub-process with pid={} to terminate", e->proc->getPid()); e->proc->close(); /** @todo: Check exit code of subprocess? */ @@ -275,7 +265,6 @@ static void register_plugin() { p.node.prepare = exec_prepare; p.node.init = exec_init; p.node.destroy = exec_destroy; - p.node.start = exec_start; p.node.stop = exec_stop; p.node.read = exec_read; p.node.write = exec_write; diff --git a/lib/nodes/file.cpp b/lib/nodes/file.cpp index 5fea6bf40..91e28190e 100644 --- a/lib/nodes/file.cpp +++ b/lib/nodes/file.cpp @@ -33,6 +33,7 @@ #include #include #include +#include using namespace villas; using namespace villas::utils; @@ -79,7 +80,7 @@ static struct timespec file_calc_offset(const struct timespec *first, const stru } } -int file_parse(struct vnode *n, json_t *cfg) +int file_parse(struct vnode *n, json_t *json) { struct file *f = (struct file *) n->_vd; @@ -92,7 +93,7 @@ int file_parse(struct vnode *n, json_t *cfg) const char *epoch = nullptr; double epoch_flt = 0; - ret = json_unpack_ex(cfg, &err, 0, "{ s: s, s?: s, s?: { s?: s, s?: F, s?: s, s?: F, s?: i, s?: i }, s?: { s?: b, s?: i } }", + ret = json_unpack_ex(json, &err, 0, "{ s: s, s?: s, s?: { s?: s, s?: F, s?: s, s?: F, s?: i, s?: i }, s?: { s?: b, s?: i } }", "uri", &uri_tmpl, "format", &format, "in", @@ -107,14 +108,14 @@ int file_parse(struct vnode *n, json_t *cfg) "buffer_size", &f->buffer_size_out ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-file"); f->epoch = time_from_double(epoch_flt); f->uri_tmpl = uri_tmpl ? strdup(uri_tmpl) : nullptr; f->format = format_type_lookup(format); if (!f->format) - error("Invalid format '%s' for node %s", format, node_name(n)); + throw RuntimeError("Invalid format '{}'", format); if (eof) { if (!strcmp(eof, "exit") || !strcmp(eof, "stop")) @@ -124,7 +125,7 @@ int file_parse(struct vnode *n, json_t *cfg) else if (!strcmp(eof, "wait")) f->eof_mode = file::EOFBehaviour::SUSPEND; else - error("Invalid mode '%s' for 'eof' setting of node %s", eof, node_name(n)); + throw RuntimeError("Invalid mode '{}' for 'eof' setting", eof); } if (epoch) { @@ -139,7 +140,7 @@ int file_parse(struct vnode *n, json_t *cfg) else if (!strcmp(epoch, "original")) f->epoch_mode = file::EpochMode::ORIGINAL; else - error("Invalid value '%s' for setting 'epoch' of node %s", epoch, node_name(n)); + throw RuntimeError("Invalid value '{}' for setting 'epoch'", epoch); } n->_vd = f; @@ -242,30 +243,29 @@ int file_start(struct vnode *n) /* Prepare file name */ f->uri = file_format_name(f->uri_tmpl, &now); - /* Check if local directory exists */ - if (aislocal(f->uri)) { - struct stat sb; - char *cpy = strdup(f->uri); - char *dir = dirname(cpy); + /* Check if directory exists */ + struct stat sb; + char *cpy = strdup(f->uri); + char *dir = dirname(cpy); - ret = stat(dir, &sb); - if (ret) { - if (errno == ENOENT || errno == ENOTDIR) { - ret = mkdir(dir, 0644); - if (ret) - serror("Failed to create directory"); - } - else if (errno != EISDIR) - serror("Failed to stat"); - } - else if (!S_ISDIR(sb.st_mode)) { + ret = stat(dir, &sb); + if (ret) { + if (errno == ENOENT || errno == ENOTDIR) { ret = mkdir(dir, 0644); if (ret) - serror("Failed to create directory"); + throw SystemError("Failed to create directory"); } - - free(cpy); + else if (errno != EISDIR) + throw SystemError("Failed to stat"); } + else if (!S_ISDIR(sb.st_mode)) { + ret = mkdir(dir, 0644); + if (ret) + throw SystemError("Failed to create directory"); + } + + free(cpy); + /* Open file */ flags = (int) SampleFlags::HAS_ALL; @@ -281,13 +281,13 @@ int file_start(struct vnode *n) return ret; if (f->buffer_size_in) { - ret = setvbuf(f->io.in.stream.std, nullptr, _IOFBF, f->buffer_size_in); + ret = setvbuf(f->io.in.stream, nullptr, _IOFBF, f->buffer_size_in); if (ret) return ret; } if (f->buffer_size_out) { - ret = setvbuf(f->io.out.stream.std, nullptr, _IOFBF, f->buffer_size_out); + ret = setvbuf(f->io.out.stream, nullptr, _IOFBF, f->buffer_size_out); if (ret) return ret; } @@ -300,7 +300,7 @@ int file_start(struct vnode *n) io_rewind(&f->io); if (io_eof(&f->io)) { - warning("Empty file"); + n->logger->warn("Empty file"); } else { struct sample s; @@ -314,7 +314,7 @@ int file_start(struct vnode *n) f->offset = file_calc_offset(&f->first, &f->epoch, f->epoch_mode); } else - warning("Failed to read first timestamp of node %s", node_name(n)); + n->logger->warn("Failed to read first timestamp"); } } @@ -363,7 +363,7 @@ retry: ret = io_scan(&f->io, smps, cnt); if (io_eof(&f->io)) { switch (f->eof_mode) { case file::EOFBehaviour::REWIND: - info("Rewind input file of node %s", node_name(n)); + n->logger->info("Rewind input file"); f->offset = file_calc_offset(&f->first, &f->epoch, f->epoch_mode); io_rewind(&f->io); @@ -375,12 +375,8 @@ retry: ret = io_scan(&f->io, smps, cnt); /* Try to download more data if this is a remote file. */ switch (f->io.mode) { - case IOMode::ADVIO: - adownload(f->io.in.stream.adv, 1); - break; - case IOMode::STDIO: - clearerr(f->io.in.stream.std); + clearerr(f->io.in.stream); break; case IOMode::CUSTOM: @@ -390,7 +386,7 @@ retry: ret = io_scan(&f->io, smps, cnt); goto retry; case file::EOFBehaviour::STOP: - info("Reached end-of-file."); + n->logger->info("Reached end-of-file."); n->state = State::STOPPING; @@ -400,7 +396,7 @@ retry: ret = io_scan(&f->io, smps, cnt); } } else - warning("Failed to read messages from node %s: reason=%d", node_name(n), ret); + n->logger->warn("Failed to read messages: reason={}", ret); return 0; } @@ -423,9 +419,9 @@ retry: ret = io_scan(&f->io, smps, cnt); /* Check for overruns */ if (steps == 0) - serror("Failed to wait for timer"); + throw SystemError("Failed to wait for timer"); else if (steps != 1) - warning("Missed steps: %" PRIu64, steps - 1); + n->logger->warn("Missed steps: {}", steps - 1); return cnt; } diff --git a/lib/nodes/fpga.cpp b/lib/nodes/fpga.cpp index f11e8351f..bc334ac1c 100644 --- a/lib/nodes/fpga.cpp +++ b/lib/nodes/fpga.cpp @@ -75,10 +75,10 @@ int fpga_type_start(node::SuperNode *sn) if (!pcieCardPlugin) throw RuntimeError("No FPGA PCIe plugin found"); - json_t *cfg = sn->getConfig(); - json_t *fpgas = json_object_get(cfg, "fpgas"); + json_t *json = sn->getConfig(); + json_t *fpgas = json_object_get(json, "fpgas"); if (!fpgas) - throw ConfigError(cfg, "node-config-fpgas", "No section 'fpgas' found in config"); + throw ConfigError(json, "node-config-fpgas", "No section 'fpgas' found in config"); // create all FPGA card instances using the corresponding plugin auto pcieCards = pcieCardPlugin->make(fpgas, pciDevices, vfioContainer); @@ -144,7 +144,7 @@ int fpga_destroy(struct vnode *n) return 0; } -int fpga_parse(struct vnode *n, json_t *cfg) +int fpga_parse(struct vnode *n, json_t *json) { int ret; struct fpga *f = (struct fpga *) n->_vd; @@ -156,7 +156,7 @@ int fpga_parse(struct vnode *n, json_t *cfg) const char *dma = nullptr; int polling = f->polling; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: s, s?: s, s?: i, s?: b }", + ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: s, s?: s, s?: i, s?: b }", "card", &card, "interface", &intf, "dma", &dma, @@ -164,7 +164,7 @@ int fpga_parse(struct vnode *n, json_t *cfg) "polling", &polling ); if (ret) - throw ConfigError(cfg, err, "node-config-fpga", "Failed to parse configuration of node {}", node_name(n)); + throw ConfigError(json, err, "node-config-node-fpga"); if (card) f->cardName = card; @@ -211,7 +211,7 @@ int fpga_prepare(struct vnode *n) }); if (it == cards.end()) - throw ConfigError(json_object_get(n->cfg, "fpga"), "node-config-fpga-card", "Invalid FPGA card name: {}", f->cardName); + throw ConfigError(json_object_get(n->config, "fpga"), "node-config-node-fpga-card", "Invalid FPGA card name: {}", f->cardName); f->card = *it; @@ -219,7 +219,7 @@ int fpga_prepare(struct vnode *n) ? f->card->lookupIp(fpga::Vlnv(FPGA_AURORA_VLNV)) : f->card->lookupIp(f->intfName); if (!intf) - throw ConfigError(n->cfg, "node-config-fpga-interface", "There is no interface IP with the name: {}", f->intfName); + throw ConfigError(n->config, "node-config-node-fpga-interface", "There is no interface IP with the name: {}", f->intfName); f->intf = std::dynamic_pointer_cast(intf); if (!f->intf) @@ -229,7 +229,7 @@ int fpga_prepare(struct vnode *n) ? f->card->lookupIp(fpga::Vlnv(FPGA_DMA_VLNV)) : f->card->lookupIp(f->dmaName); if (!dma) - throw ConfigError(n->cfg, "node-config-fpga-dma", "There is no DMA IP with the name: {}", f->dmaName); + throw ConfigError(n->config, "node-config-node-fpga-dma", "There is no DMA IP with the name: {}", f->dmaName); f->dma = std::dynamic_pointer_cast(dma); if (!f->dma) diff --git a/lib/nodes/iec61850_sv.cpp b/lib/nodes/iec61850_sv.cpp index fdb5719d2..d29d6dd22 100644 --- a/lib/nodes/iec61850_sv.cpp +++ b/lib/nodes/iec61850_sv.cpp @@ -47,11 +47,11 @@ static void iec61850_sv_listener(SVSubscriber subscriber, void *ctx, SVSubscribe int confrev = SVSubscriber_ASDU_getConfRev(asdu); int sz; - debug(10, "Received SV: svid=%s, smpcnt=%i, confrev=%u", svid, smpcnt, confrev); + n->logger->debug("Received SV: svid={}, smpcnt={}, confrev={}", svid, smpcnt, confrev); sz = SVSubscriber_ASDU_getDataSize(asdu); if (sz < i->in.total_size) { - warning("Received truncated ASDU: size=%d, expected=%d", SVSubscriber_ASDU_getDataSize(asdu), i->in.total_size); + n->node->warn("Received truncated ASDU: size={}, expected={}", SVSubscriber_ASDU_getDataSize(asdu), i->in.total_size); return; } @@ -67,7 +67,7 @@ static void iec61850_sv_listener(SVSubscriber subscriber, void *ctx, SVSubscribe smp = sample_alloc(&i->in.pool); if (!smp) { - warning("Pool underrun in subscriber of %s", node_name(n)); + n->logger->warn("Pool underrun in subscriber"); return; } @@ -173,7 +173,7 @@ int iec61850_sv_parse(struct vnode *n, json_t *json) "dst_address", &dst_address ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-iec61850-sv"); if (interface) i->interface = strdup(interface); @@ -200,7 +200,7 @@ int iec61850_sv_parse(struct vnode *n, json_t *json) "vlan_priority", &i->out.vlan_priority ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json_out, err, "node-config-node-iec61850-sv-out"); if (smpmod) { if (!strcmp(smpmod, "per_nominal_period")) @@ -210,14 +210,14 @@ int iec61850_sv_parse(struct vnode *n, json_t *json) else if (!strcmp(smpmod, "seconds_per_sample")) i->out.smpmod = IEC61850_SV_SMPMOD_SECONDS_PER_SAMPLE; else - error("Invalid value '%s' for setting 'smpmod'", smpmod); + throw RuntimeError("Invalid value '{}' for setting 'smpmod'", smpmod); } i->out.svid = svid ? strdup(svid) : nullptr; ret = iec61850_parse_signals(json_signals, &i->out.signals, &n->out.signals); if (ret <= 0) - error("Failed to parse setting 'signals' of node %s", node_name(n)); + throw RuntimeError("Failed to parse setting 'signals'"); i->out.total_size = ret; } @@ -230,11 +230,11 @@ int iec61850_sv_parse(struct vnode *n, json_t *json) "signals", &json_signals ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json_in, err, "node-config-node-iec61850-in"); ret = iec61850_parse_signals(json_signals, &i->in.signals, &n->in.signals); if (ret <= 0) - error("Failed to parse setting 'signals' of node %s", node_name(n)); + throw RuntimeError("Failed to parse setting 'signals'"); i->in.total_size = ret; } diff --git a/lib/nodes/infiniband.cpp b/lib/nodes/infiniband.cpp index a97d18c03..11d668b07 100644 --- a/lib/nodes/infiniband.cpp +++ b/lib/nodes/infiniband.cpp @@ -41,7 +41,8 @@ static int ib_disconnect(struct vnode *n) struct infiniband *ib = (struct infiniband *) n->_vd; struct ibv_wc wc[MAX(ib->recv_cq_size, ib->send_cq_size)]; int wcs; - debug(LOG_IB | 1, "Starting to clean up"); + + n->logger->debug("Starting to clean up"); rdma_disconnect(ib->ctx.id); @@ -63,7 +64,8 @@ static int ib_disconnect(struct vnode *n) /* Destroy QP */ rdma_destroy_qp(ib->ctx.id); - debug(LOG_IB | 3, "Destroyed QP"); + + n->logger->debug("Destroyed QP"); return ib->stopThreads; } @@ -73,20 +75,20 @@ static void ib_build_ibv(struct vnode *n) struct infiniband *ib = (struct infiniband *) n->_vd; int ret; - debug(LOG_IB | 1, "Starting to build IBV components"); + n->logger->debug("Starting to build IBV components"); /* Create completion queues (No completion channel!) */ ib->ctx.recv_cq = ibv_create_cq(ib->ctx.id->verbs, ib->recv_cq_size, nullptr, nullptr, 0); if (!ib->ctx.recv_cq) - error("Could not create receive completion queue in node %s", node_name(n)); + throw RuntimeError("Could not create receive completion queue"); - debug(LOG_IB | 3, "Created receive Completion Queue"); + n->logger->debug("Created receive Completion Queue"); ib->ctx.send_cq = ibv_create_cq(ib->ctx.id->verbs, ib->send_cq_size, nullptr, nullptr, 0); if (!ib->ctx.send_cq) - error("Could not create send completion queue in node %s", node_name(n)); + throw RuntimeError("Could not create send completion queue"); - debug(LOG_IB | 3, "Created send Completion Queue"); + n->logger->debug("Created send Completion Queue"); /* Prepare remaining Queue Pair (QP) attributes */ ib->qp_init.send_cq = ib->ctx.send_cq; @@ -95,13 +97,13 @@ static void ib_build_ibv(struct vnode *n) /* Create the actual QP */ ret = rdma_create_qp(ib->ctx.id, ib->ctx.pd, &ib->qp_init); if (ret) - error("Failed to create Queue Pair in node %s", node_name(n)); + throw RuntimeError("Failed to create Queue Pair"); - debug(LOG_IB | 3, "Created Queue Pair with %i receive and %i send elements", + n->logger->debug("Created Queue Pair with {} receive and {} send elements", ib->qp_init.cap.max_recv_wr, ib->qp_init.cap.max_send_wr); if (ib->conn.send_inline) - info("Maximum inline size is set to %i byte", ib->qp_init.cap.max_inline_data); + n->logger->info("Maximum inline size is set to {} byte", ib->qp_init.cap.max_inline_data); } static int ib_addr_resolved(struct vnode *n) @@ -109,7 +111,7 @@ static int ib_addr_resolved(struct vnode *n) struct infiniband *ib = (struct infiniband *) n->_vd; int ret; - debug(LOG_IB | 1, "Successfully resolved address"); + n->logger->debug("Successfully resolved address"); /* Build all components from IB Verbs */ ib_build_ibv(n); @@ -117,7 +119,7 @@ static int ib_addr_resolved(struct vnode *n) /* Resolve address */ ret = rdma_resolve_route(ib->ctx.id, ib->conn.timeout); if (ret) - error("Failed to resolve route in node %s", node_name(n)); + throw RuntimeError("Failed to resolve route"); return 0; } @@ -133,9 +135,9 @@ static int ib_route_resolved(struct vnode *n) /* Send connection request */ ret = rdma_connect(ib->ctx.id, &cm_params); if (ret) - error("Failed to connect in node %s", node_name(n)); + throw RuntimeError("Failed to connect"); - debug(LOG_IB | 1, "Called rdma_connect"); + n->logger->debug("Called rdma_connect"); return 0; } @@ -144,7 +146,8 @@ static int ib_connect_request(struct vnode *n, struct rdma_cm_id *id) { struct infiniband *ib = (struct infiniband *) n->_vd; int ret; - debug(LOG_IB | 1, "Received a connection request!"); + + n->logger->debug("Received a connection request!"); ib->ctx.id = id; ib_build_ibv(n); @@ -155,9 +158,9 @@ static int ib_connect_request(struct vnode *n, struct rdma_cm_id *id) /* Accept connection request */ ret = rdma_accept(ib->ctx.id, &cm_params); if (ret) - error("Failed to connect in node %s", node_name(n)); + throw RuntimeError("Failed to connect"); - info("Successfully accepted connection request in node %s", node_name(n)); + n->logger->info("Successfully accepted connection request"); return 0; } @@ -171,7 +174,7 @@ int ib_reverse(struct vnode *n) return 0; } -int ib_parse(struct vnode *n, json_t *cfg) +int ib_parse(struct vnode *n, json_t *json) { struct infiniband *ib = (struct infiniband *) n->_vd; @@ -195,13 +198,13 @@ int ib_parse(struct vnode *n, json_t *cfg) json_t *json_out = nullptr; json_error_t err; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: o, s?: o, s?: s }", + ret = json_unpack_ex(json, &err, 0, "{ s?: o, s?: o, s?: s }", "in", &json_in, "out", &json_out, "rdma_transport_mode", &transport_mode ); if (ret) - jerror(&err, "Failed to parse in/out json blocks"); + throw ConfigError(json, err, "node-config-node-ib"); if (json_in) { @@ -213,7 +216,7 @@ int ib_parse(struct vnode *n, json_t *cfg) "buffer_subtraction", &buffer_subtraction ); if (ret) - jerror(&err, "Failed to parse input configuration of node %s", node_name(n)); + throw ConfigError(json_in, err, "node-config-node-ib-in"); } if (json_out) { @@ -229,18 +232,18 @@ int ib_parse(struct vnode *n, json_t *cfg) "periodic_signaling", &ib->periodic_signaling ); if (ret) - jerror(&err, "Failed to parse output configuration of node %s", node_name(n)); + throw ConfigError(json_out, err, "node-config-node-ib-out"); if (remote) { ib->is_source = 1; - debug(LOG_IB | 3, "Node %s is up as source and target", node_name(n)); + n->logger->debug("Setup as source and target"); } } else { ib->is_source = 0; - debug(LOG_IB | 3, "Node %s is up as target", node_name(n)); + n->logger->debug("Setup as target"); } /* Set fallback mode */ @@ -253,7 +256,7 @@ int ib_parse(struct vnode *n, json_t *cfg) /* Set buffer subtraction */ ib->conn.buffer_subtraction = buffer_subtraction; - debug(LOG_IB | 4, "Set buffer subtraction to %i in node %s", buffer_subtraction, node_name(n)); + n->logger->debug("Set buffer subtraction to {}", buffer_subtraction); /* Translate IP:PORT to a struct addrinfo */ char *ip_adr = strtok_r(local, ":", &lasts); @@ -261,10 +264,9 @@ int ib_parse(struct vnode *n, json_t *cfg) ret = getaddrinfo(ip_adr, port, nullptr, &ib->conn.src_addr); if (ret) - error("Failed to resolve local address '%s' of node %s: %s", - local, node_name(n), gai_strerror(ret)); + throw RuntimeError("Failed to resolve local address '{}': {}", local, gai_strerror(ret)); - debug(LOG_IB | 4, "Translated %s:%s to a struct addrinfo in node %s", ip_adr, port, node_name(n)); + n->logger->debug("Translated {}:{} to a struct addrinfo", ip_adr, port); /* Translate port space */ if (strcmp(transport_mode, "RC") == 0) { @@ -276,8 +278,8 @@ int ib_parse(struct vnode *n, json_t *cfg) ib->conn.port_space = RDMA_PS_IB; ib->qp_init.qp_type = IBV_QPT_UC; #else - error("Unreliable Connected (UC) mode is only available with an adapted version of librdma. " - "Please read the Infiniband node type Documentation for more information on UC!"); + throw RuntimeError("Unreliable Connected (UC) mode is only available with an adapted version of librdma. " + "Please read the Infiniband node type Documentation for more information on UC!"); #endif } else if (strcmp(transport_mode, "UD") == 0) { @@ -285,35 +287,34 @@ int ib_parse(struct vnode *n, json_t *cfg) ib->qp_init.qp_type = IBV_QPT_UD; } else - error("transport_mode = %s is not a valid transport mode in node %s!", - transport_mode, node_name(n)); + throw RuntimeError("Invalid transport_mode = '{}'!", transport_mode); - debug(LOG_IB | 4, "Set transport mode to %s in node %s", transport_mode, node_name(n)); + n->logger->debug("Set transport mode to {}", transport_mode); /* Set timeout */ ib->conn.timeout = timeout; - debug(LOG_IB | 4, "Set timeout to %i in node %s", timeout, node_name(n)); + n->logger->debug("Set timeout to {}", timeout); /* Set completion queue size */ ib->recv_cq_size = recv_cq_size; ib->send_cq_size = send_cq_size; - debug(LOG_IB | 4, "Set Completion Queue size to %i & %i (in & out) in node %s", - recv_cq_size, send_cq_size, node_name(n)); + n->logger->debug("Set Completion Queue size to {} & {} (in & out)", + recv_cq_size, send_cq_size); /* Translate inline mode */ ib->conn.send_inline = send_inline; - debug(LOG_IB | 4, "Set send_inline to %i in node %s", send_inline, node_name(n)); + n->logger->debug("Set send_inline to {}", send_inline); /* Set max. send and receive Work Requests */ ib->qp_init.cap.max_send_wr = max_send_wr; ib->qp_init.cap.max_recv_wr = max_recv_wr; - debug(LOG_IB | 4, "Set max_send_wr and max_recv_wr in node %s to %i and %i, respectively", - node_name(n), max_send_wr, max_recv_wr); + n->logger->debug("Set max_send_wr and max_recv_wr to {} and {}, respectively", + max_send_wr, max_recv_wr); /* Set available receive Work Requests to 0 */ ib->conn.available_recv_wrs = 0; @@ -333,10 +334,9 @@ int ib_parse(struct vnode *n, json_t *cfg) ret = getaddrinfo(ip_adr, port, nullptr, &ib->conn.dst_addr); if (ret) - error("Failed to resolve remote address '%s' of node %s: %s", - remote, node_name(n), gai_strerror(ret)); + throw RuntimeError("Failed to resolve remote address '{}': {}", remote, gai_strerror(ret)); - debug(LOG_IB | 4, "Translated %s:%s to a struct addrinfo", ip_adr, port); + n->logger->debug("Translated {}:{} to a struct addrinfo", ip_adr, port); } return 0; @@ -348,17 +348,17 @@ int ib_check(struct vnode *n) /* Check if read substraction makes sense */ if (ib->conn.buffer_subtraction < 2 * n->in.vectorize) - error("The buffer substraction value must be bigger than 2 * in.vectorize"); + throw RuntimeError("The buffer substraction value must be bigger than 2 * in.vectorize"); if (ib->conn.buffer_subtraction >= ib->qp_init.cap.max_recv_wr - n->in.vectorize) - error("The buffer substraction value cannot be bigger than in.max_wrs - in.vectorize"); + throw RuntimeError("The buffer substraction value cannot be bigger than in.max_wrs - in.vectorize"); /* Check if the set value is a power of 2, and warn the user if this is not the case */ unsigned max_send_pow = (int) pow(2, ceil(log2(ib->qp_init.cap.max_send_wr))); unsigned max_recv_pow = (int) pow(2, ceil(log2(ib->qp_init.cap.max_recv_wr))); if (ib->qp_init.cap.max_send_wr != max_send_pow) { - warning("Max nr. of send WRs (%i) is not a power of 2! It will be changed to a power of 2: %i", + n->logger->warn("Max nr. of send WRs ({}) is not a power of 2! It will be changed to a power of 2: {}", ib->qp_init.cap.max_send_wr, max_send_pow); /* Change it now, because otherwise errors are possible in ib_start(). */ @@ -366,7 +366,7 @@ int ib_check(struct vnode *n) } if (ib->qp_init.cap.max_recv_wr != max_recv_pow) { - warning("Max nr. of recv WRs (%i) is not a power of 2! It will be changed to a power of 2: %i", + n->logger->warn("Max nr. of recv WRs ({}) is not a power of 2! It will be changed to a power of 2: {}", ib->qp_init.cap.max_recv_wr, max_recv_pow); /* Change it now, because otherwise errors are possible in ib_start(). */ @@ -375,10 +375,10 @@ int ib_check(struct vnode *n) /* Check maximum size of max_recv_wr and max_send_wr */ if (ib->qp_init.cap.max_send_wr > 8192) - warning("Max number of send WRs (%i) is bigger than send queue!", ib->qp_init.cap.max_send_wr); + n->logger->warn("Max number of send WRs ({}) is bigger than send queue!", ib->qp_init.cap.max_send_wr); if (ib->qp_init.cap.max_recv_wr > 8192) - warning("Max number of receive WRs (%i) is bigger than send queue!", ib->qp_init.cap.max_recv_wr); + n->logger->warn("Max number of receive WRs ({}) is bigger than send queue!", ib->qp_init.cap.max_recv_wr); /* Set periodic signaling * This is done here, so that it uses the checked max_send_wr value */ @@ -387,7 +387,7 @@ int ib_check(struct vnode *n) /* Warn user if he changed the default inline value */ if (ib->qp_init.cap.max_inline_data != 0) - warning("You changed the default value of max_inline_data. This might influence the maximum number " + n->logger->warn("You changed the default value of max_inline_data. This might influence the maximum number " "of outstanding Work Requests in the Queue Pair and can be a reason for the Queue Pair creation to fail"); return 0; @@ -420,8 +420,8 @@ static void ib_create_bind_id(struct vnode *n) * 2. Edit librdmacm/cma.c and remove the keyword 'static' in front of: * * static int rdma_create_id2(struct rdma_event_channel *channel, - * struct rdma_cm_id **id, void *context, - * enum rdma_port_space ps, enum ibv_qp_type qp_type) + * struct rdma_cm_id **id, void *context, + * enum rdma_port_space ps, enum ibv_qp_type qp_type) * * 3. Edit librdmacm/rdma_cma.h and add the following two entries to the file: * @@ -445,17 +445,16 @@ static void ib_create_bind_id(struct vnode *n) ret = rdma_create_id(ib->ctx.ec, &ib->ctx.id, nullptr, ib->conn.port_space); #endif if (ret) - error("Failed to create rdma_cm_id of node %s: %s", node_name(n), gai_strerror(ret)); + throw RuntimeError("Failed to create rdma_cm_id: {}", gai_strerror(ret)); - debug(LOG_IB | 3, "Created rdma_cm_id"); + n->logger->debug("Created rdma_cm_id"); /* Bind rdma_cm_id to the HCA */ ret = rdma_bind_addr(ib->ctx.id, ib->conn.src_addr->ai_addr); if (ret) - error("Failed to bind to local device of node %s: %s", - node_name(n), gai_strerror(ret)); + throw RuntimeError("Failed to bind to local device: {}", gai_strerror(ret)); - debug(LOG_IB | 3, "Bound rdma_cm_id to Infiniband device"); + n->logger->debug("Bound rdma_cm_id to Infiniband device"); /* The ID will be overwritten for the target. If the event type is * RDMA_CM_EVENT_CONNECT_REQUEST, >then this references a new id for @@ -470,11 +469,10 @@ static void ib_continue_as_listen(struct vnode *n, struct rdma_cm_event *event) int ret; if (ib->conn.use_fallback) - warning("Trying to continue as listening node"); + n->logger->warn("Trying to continue as listening node"); else - error("Cannot establish a connection with remote host! If you want that %s tries to " - "continue as listening node in such cases, set use_fallback = true in the configuration", - node_name(n)); + throw RuntimeError("Cannot establish a connection with remote host! If you want that {} tries to " + "continue as listening node in such cases, set use_fallback = true in the configuration"); n->state = State::STARTED; @@ -490,84 +488,84 @@ static void ib_continue_as_listen(struct vnode *n, struct rdma_cm_event *event) /* Listen to id for events */ ret = rdma_listen(ib->ctx.listen_id, 10); if (ret) - error("Failed to listen to rdma_cm_id on node %s", node_name(n)); + throw RuntimeError("Failed to listen to rdma_cm_id"); /* Node is not a source (and will not send data */ ib->is_source = 0; - info("Node %s is set to listening mode", node_name(n)); + n->logger->info("Use listening mode"); } -void * ib_rdma_cm_event_thread(void *n) +void * ib_rdma_cm_event_thread(void *ctx) { - struct vnode *node = (struct vnode *) n; - struct infiniband *ib = (struct infiniband *) node->_vd; + struct vnode *n = (struct vnode *) ctx; + struct infiniband *ib = (struct infiniband *) n->_vd; struct rdma_cm_event *event; int ret = 0; - debug(LOG_IB | 1, "Started rdma_cm_event thread of node %s", node_name(node)); + n->logger->debug("Started rdma_cm_event thread"); /* Wait until node is completely started */ - while (node->state != State::STARTED); + while (n->state != State::STARTED); /* Monitor event channel */ while (rdma_get_cm_event(ib->ctx.ec, &event) == 0) { - debug(LOG_IB | 2, "Received communication event: %s", rdma_event_str(event->event)); + n->logger->debug("Received communication event: {}", rdma_event_str(event->event)); switch(event->event) { case RDMA_CM_EVENT_ADDR_RESOLVED: - ret = ib_addr_resolved(node); + ret = ib_addr_resolved(n); break; case RDMA_CM_EVENT_ADDR_ERROR: - warning("Address resolution (rdma_resolve_addr) failed!"); + n->logger->warn("Address resolution (rdma_resolve_addr) failed!"); - ib_continue_as_listen(node, event); + ib_continue_as_listen(n, event); break; case RDMA_CM_EVENT_ROUTE_RESOLVED: - ret = ib_route_resolved(node); + ret = ib_route_resolved(n); break; case RDMA_CM_EVENT_ROUTE_ERROR: - warning("Route resolution (rdma_resovle_route) failed!"); + n->logger->warn("Route resolution (rdma_resovle_route) failed!"); - ib_continue_as_listen(node, event); + ib_continue_as_listen(n, event); break; case RDMA_CM_EVENT_UNREACHABLE: - warning("Remote server unreachable!"); + n->logger->warn("Remote server unreachable!"); - ib_continue_as_listen(node, event); + ib_continue_as_listen(n, event); break; case RDMA_CM_EVENT_CONNECT_REQUEST: - ret = ib_connect_request(node, event->id); + ret = ib_connect_request(n, event->id); /* A target UDP node will never really connect. In order to receive data, * we set it to connected after it answered the connection request * with rdma_connect. */ if (ib->conn.port_space == RDMA_PS_UDP && !ib->is_source) - node->state = State::CONNECTED; + n->state = State::CONNECTED; else - node->state = State::PENDING_CONNECT; + n->state = State::PENDING_CONNECT; break; case RDMA_CM_EVENT_CONNECT_ERROR: - warning("An error has occurred trying to establish a connection!"); + n->logger->warn("An error has occurred trying to establish a connection!"); - ib_continue_as_listen(node, event); + ib_continue_as_listen(n, event); break; case RDMA_CM_EVENT_REJECTED: - warning("Connection request or response was rejected by the remote end point!"); + n->logger->warn("Connection request or response was rejected by the remote end point!"); - ib_continue_as_listen(node, event); + ib_continue_as_listen(n, event); break; @@ -578,19 +576,19 @@ void * ib_rdma_cm_event_thread(void *n) ib->conn.ud.ah = ibv_create_ah(ib->ctx.pd, &ib->conn.ud.ud.ah_attr); } - node->state = State::CONNECTED; + n->state = State::CONNECTED; - info("Connection established in node %s", node_name(node)); + n->logger->info("Connection established"); break; case RDMA_CM_EVENT_DISCONNECTED: - node->state = State::STARTED; + n->state = State::STARTED; - ret = ib_disconnect(node); + ret = ib_disconnect(n); if (!ret) - info("Host disconnected. Ready to accept new connections."); + n->logger->info("Host disconnected. Ready to accept new connections."); break; @@ -598,7 +596,7 @@ void * ib_rdma_cm_event_thread(void *n) break; default: - error("Unknown event occurred: %u", event->event); + throw RuntimeError("Unknown event occurred: {}", event->event); } rdma_ack_cm_event(event); @@ -615,43 +613,42 @@ int ib_start(struct vnode *n) struct infiniband *ib = (struct infiniband *) n->_vd; int ret; - debug(LOG_IB | 1, "Started ib_start"); + n->logger->debug("Started ib_start"); /* Create event channel */ ib->ctx.ec = rdma_create_event_channel(); if (!ib->ctx.ec) - error("Failed to create event channel in node %s!", node_name(n)); + throw RuntimeError("Failed to create event channel!"); - debug(LOG_IB | 3, "Created event channel"); + n->logger->debug("Created event channel"); /* Create rdma_cm_id and bind to device */ ib_create_bind_id(n); - debug(LOG_IB | 3, "Initialized Work Completion Buffer"); + n->logger->debug("Initialized Work Completion Buffer"); /* Resolve address or listen to rdma_cm_id */ if (ib->is_source) { /* Resolve address */ ret = rdma_resolve_addr(ib->ctx.id, nullptr, ib->conn.dst_addr->ai_addr, ib->conn.timeout); if (ret) - error("Failed to resolve remote address after %ims of node %s: %s", - ib->conn.timeout, node_name(n), gai_strerror(ret)); + throw RuntimeError("Failed to resolve remote address after {}ms: {}", ib->conn.timeout, gai_strerror(ret)); } else { /* Listen on rdma_cm_id for events */ ret = rdma_listen(ib->ctx.listen_id, 10); if (ret) - error("Failed to listen to rdma_cm_id on node %s", node_name(n)); + throw RuntimeError("Failed to listen to rdma_cm_id"); - debug(LOG_IB | 3, "Started to listen to rdma_cm_id"); + n->logger->debug("Started to listen to rdma_cm_id"); } /* Allocate protection domain */ ib->ctx.pd = ibv_alloc_pd(ib->ctx.id->verbs); if (!ib->ctx.pd) - error("Could not allocate protection domain in node %s", node_name(n)); + throw RuntimeError("Could not allocate protection domain"); - debug(LOG_IB | 3, "Allocated Protection Domain"); + n->logger->debug("Allocated Protection Domain"); /* Allocate space for 40 Byte GHR. We don't use this. */ if (ib->conn.port_space == RDMA_PS_UDP) { @@ -665,13 +662,12 @@ int ib_start(struct vnode *n) /* Several events should occur on the event channel, to make * sure the nodes are succesfully connected. */ - debug(LOG_IB | 1, "Starting to monitor events on rdma_cm_id"); + n->logger->debug("Starting to monitor events on rdma_cm_id"); /* Create thread to monitor rdma_cm_event channel */ ret = pthread_create(&ib->conn.rdma_cm_event_thread, nullptr, ib_rdma_cm_event_thread, n); if (ret) - error("Failed to create thread to monitor rdma_cm events in node %s: %s", - node_name(n), gai_strerror(ret)); + throw RuntimeError("Failed to create thread to monitor rdma_cm events: {}", gai_strerror(ret)); return 0; } @@ -681,7 +677,7 @@ int ib_stop(struct vnode *n) struct infiniband *ib = (struct infiniband *) n->_vd; int ret; - debug(LOG_IB | 1, "Called ib_stop"); + n->logger->debug("Called ib_stop"); ib->stopThreads = 1; @@ -693,39 +689,38 @@ int ib_stop(struct vnode *n) ret = rdma_disconnect(ib->ctx.id); if (ret) - error("Error while calling rdma_disconnect in node %s: %s", - node_name(n), gai_strerror(ret)); + throw RuntimeError("Error while calling rdma_disconnect: {}", gai_strerror(ret)); - debug(LOG_IB | 3, "Called rdma_disconnect"); + n->logger->debug("Called rdma_disconnect"); } else { pthread_cancel(ib->conn.rdma_cm_event_thread); - debug(LOG_IB | 3, "Called pthread_cancel() on communication management thread."); + n->logger->debug("Called pthread_cancel() on communication management thread."); } - info("Disconnecting... Waiting for threads to join."); + n->logger->info("Disconnecting... Waiting for threads to join."); /* Wait for event thread to join */ ret = pthread_join(ib->conn.rdma_cm_event_thread, nullptr); if (ret) - error("Error while joining rdma_cm_event_thread in node %s: %i", node_name(n), ret); + throw RuntimeError("Error while joining rdma_cm_event_thread: {}", ret); - debug(LOG_IB | 3, "Joined rdma_cm_event_thread"); + n->logger->debug("Joined rdma_cm_event_thread"); /* Destroy RDMA CM ID */ rdma_destroy_id(ib->ctx.id); - debug(LOG_IB | 3, "Destroyed rdma_cm_id"); + n->logger->debug("Destroyed rdma_cm_id"); /* Dealloc Protection Domain */ ibv_dealloc_pd(ib->ctx.pd); - debug(LOG_IB | 3, "Destroyed protection domain"); + n->logger->debug("Destroyed protection domain"); /* Destroy event channel */ rdma_destroy_event_channel(ib->ctx.ec); - debug(LOG_IB | 3, "Destroyed event channel"); + n->logger->debug("Destroyed event channel"); - info("Successfully stopped %s", node_name(n)); + n->logger->info("Successfully stopped node"); return 0; } @@ -740,7 +735,7 @@ int ib_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *rele struct timespec ts_receive; int ret = 0, wcs = 0, read_values = 0, max_wr_post; - debug(LOG_IB | 15, "ib_read is called"); + n->logger->debug("ib_read is called"); if (n->state == State::CONNECTED || n->state == State::PENDING_CONNECT) { @@ -763,7 +758,7 @@ int ib_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *rele /* Get time directly after something arrived in Completion Queue */ ts_receive = time_now(); - debug(LOG_IB | 10, "Received %i Work Completions", wcs); + n->logger->debug("Received {} Work Completions", wcs); read_values = wcs; /* Value to return */ max_wr_post = wcs; /* Make space free in smps[] */ @@ -829,17 +824,15 @@ int ib_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *rele wr[max_wr_post-1].next = nullptr; - debug(LOG_IB | 5, "Prepared %i new receive Work Requests", max_wr_post); - debug(LOG_IB | 5, "%i receive Work Requests in Receive Queue", ib->conn.available_recv_wrs); + n->logger->debug("Prepared {} new receive Work Requests", max_wr_post); + n->logger->debug("{} receive Work Requests in Receive Queue", ib->conn.available_recv_wrs); /* Post list of Work Requests */ ret = ibv_post_recv(ib->ctx.id->qp, &wr[0], &bad_wr); - if (ret) - error("Was unable to post receive WR in node %s: %i, bad WR ID: 0x%" PRIu64, - node_name(n), ret, bad_wr->wr_id); + throw RuntimeError("Was unable to post receive WR: {}, bad WR ID: {:#x}", ret, bad_wr->wr_id); - debug(LOG_IB | 10, "Succesfully posted receive Work Requests"); + n->logger->debug("Succesfully posted receive Work Requests"); /* Doesn't start if wcs == 0 */ for (int j = 0; j < wcs; j++) { @@ -849,10 +842,10 @@ int ib_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *rele } if (wc[j].status == IBV_WC_WR_FLUSH_ERR) - debug(LOG_IB | 5, "Received IBV_WC_WR_FLUSH_ERR (ib_read). Ignore it."); + n->logger->debug("Received IBV_WC_WR_FLUSH_ERR (ib_read). Ignore it."); else if (wc[j].status != IBV_WC_SUCCESS) - warning("Work Completion status was not IBV_WC_SUCCES in node %s: %i", - node_name(n), wc[j].status); + n->logger->warn("Work Completion status was not IBV_WC_SUCCESS: {}", + wc[j].status); /* 32 byte of meta data is always transferred. We should substract it. * Furthermore, in case of an unreliable connection, a 40 byte @@ -883,7 +876,7 @@ int ib_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *rel int ret; unsigned sent = 0; /* Used for first loop: prepare work requests to post to send queue */ - debug(LOG_IB | 10, "ib_write is called"); + n->logger->debug("ib_write is called"); if (n->state == State::CONNECTED) { *release = 0; @@ -936,7 +929,7 @@ int ib_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *rel && ((++ib->signaling_counter % ib->periodic_signaling) != 0) ? ib->conn.send_inline : 0; - debug(LOG_IB | 10, "Sample will be send inline [0/1]: %i", send_inline); + n->logger->debug("Sample will be send inline [0/1]: {}", send_inline); /* Set Send Work Request */ wr[sent].wr_id = (uintptr_t) smps[sent]; @@ -948,12 +941,12 @@ int ib_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *rel wr[sent].opcode = IBV_WR_SEND; } - debug(LOG_IB | 10, "Prepared %i send Work Requests", cnt); + n->logger->debug("Prepared {} send Work Requests", cnt); wr[cnt-1].next = nullptr; /* Send linked list of Work Requests */ ret = ibv_post_send(ib->ctx.id->qp, wr, &bad_wr); - debug(LOG_IB | 4, "Posted send Work Requests"); + n->logger->debug("Posted send Work Requests"); /* Reorder list. Place inline and unposted samples to the top * m will always be equal or smaller than *release @@ -966,8 +959,8 @@ int ib_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *rel /* The remaining work requests will be bad. Ripple through list * and prepare them to be released */ - debug(LOG_IB | 4, "Bad WR occured with ID: 0x%" PRIu64 " and S/G address: 0x%px: %i", - bad_wr->wr_id, bad_wr->sg_list, ret); + n->logger->debug("Bad WR occured with ID: {:#x} and S/G address: {:#x}: {}", + bad_wr->wr_id, bad_wr->sg_list, ret); while (1) { smps[*release] = smps[m]; @@ -983,24 +976,23 @@ int ib_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *rel (*release)++; } - } - debug(LOG_IB | 4, "%i samples will be released (before WC)", *release); + n->logger->debug("{} samples will be released (before WC)", *release); /* Try to grab as many CQEs from CQ as there is space in *smps[] */ ret = ibv_poll_cq(ib->ctx.send_cq, cnt - *release, wc); for (int i = 0; i < ret; i++) { if (wc[i].status != IBV_WC_SUCCESS && wc[i].status != IBV_WC_WR_FLUSH_ERR) - warning("Work Completion status was not IBV_WC_SUCCES in node %s: %i", - node_name(n), wc[i].status); + n->logger->warn("Work Completion status was not IBV_WC_SUCCESS: {}", + wc[i].status); smps[*release] = (struct sample *) (wc[i].wr_id); (*release)++; } - debug(LOG_IB | 4, "%i samples will be released (after WC)", *release); + n->logger->debug("{} samples will be released (after WC)", *release); } return sent; diff --git a/lib/nodes/influxdb.cpp b/lib/nodes/influxdb.cpp index e30b9e101..9eefca3b1 100644 --- a/lib/nodes/influxdb.cpp +++ b/lib/nodes/influxdb.cpp @@ -32,7 +32,9 @@ #include #include #include +#include +using namespace villas; using namespace villas::utils; int influxdb_parse(struct vnode *n, json_t *json) @@ -50,7 +52,7 @@ int influxdb_parse(struct vnode *n, json_t *json) "key", &key ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-influx"); tmp = strdup(server); @@ -79,21 +81,19 @@ int influxdb_open(struct vnode *n) ret = getaddrinfo(i->host, i->port, &hints, &servinfo); if (ret) - error("Failed to lookup server: %s", gai_strerror(ret)); + throw RuntimeError("Failed to lookup server: {}", gai_strerror(ret)); /* Loop through all the results and connect to the first we can */ for (p = servinfo; p != nullptr; p = p->ai_next) { i->sd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); - if (i->sd == -1) { - serror("socket"); - continue; - } + if (i->sd == -1) + throw SystemError("Failed to create socket"); ret = connect(i->sd, p->ai_addr, p->ai_addrlen); if (ret == -1) { - warning("connect"); - close(i->sd); - continue; + n->logger->warn("Connect failed: {}", strerror(errno)); + close(i->sd); + continue; } /* If we get here, we must have connected successfully */ @@ -143,7 +143,7 @@ int influxdb_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigne sig->type != SignalType::INTEGER && sig->type != SignalType::COMPLEX ) { - warning("Unsupported signal format for node %s. Skipping", node_name(n)); + n->logger->warn("Unsupported signal format. Skipping"); continue; } @@ -196,7 +196,7 @@ int influxdb_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigne if (sentlen < 0) return -1; else if (sentlen < buflen) - warning("Partial sent"); + n->logger->warn("Partial sent"); free(buf); diff --git a/lib/nodes/loopback.cpp b/lib/nodes/loopback.cpp index 586967fe4..c62b74995 100644 --- a/lib/nodes/loopback.cpp +++ b/lib/nodes/loopback.cpp @@ -44,7 +44,7 @@ int loopback_init(struct vnode *n) return 0; } -int loopback_parse(struct vnode *n, json_t *cfg) +int loopback_parse(struct vnode *n, json_t *json) { struct loopback *l = (struct loopback *) n->_vd; const char *mode_str = nullptr; @@ -52,12 +52,12 @@ int loopback_parse(struct vnode *n, json_t *cfg) json_error_t err; int ret; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: i, s?: s }", + ret = json_unpack_ex(json, &err, 0, "{ s?: i, s?: s }", "queuelen", &l->queuelen, "mode", &mode_str ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-loopback"); if (mode_str) { if (!strcmp(mode_str, "auto")) @@ -75,7 +75,7 @@ int loopback_parse(struct vnode *n, json_t *cfg) l->mode = QueueSignalledMode::PIPE; #endif /* __APPLE__ */ else - error("Unknown mode '%s' in node %s", mode_str, node_name(n)); + throw ConfigError(json, "node-config-node-loopback-mode", "Unknown mode '{}'", mode_str); } return 0; diff --git a/lib/nodes/mqtt.cpp b/lib/nodes/mqtt.cpp index d6428c9cf..624403a2f 100644 --- a/lib/nodes/mqtt.cpp +++ b/lib/nodes/mqtt.cpp @@ -27,6 +27,7 @@ #include #include #include +#include using namespace villas; using namespace villas::utils; @@ -34,6 +35,7 @@ using namespace villas::utils; // Each process has a list of clients for which a thread invokes the mosquitto loop static struct vlist clients; static pthread_t thread; +static Logger logger; static void * mosquitto_loop_thread(void *ctx) { @@ -41,30 +43,28 @@ static void * mosquitto_loop_thread(void *ctx) // Set the cancel type of this thread to async ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, nullptr); - if (ret != 0) { - error("Unable to set cancel type of MQTT communication thread to asynchronous."); - return nullptr; - } + if (ret != 0) + throw RuntimeError("Unable to set cancel type of MQTT communication thread to asynchronous."); while (true) { for (unsigned i = 0; i < vlist_length(&clients); i++) { - struct vnode *node = (struct vnode *) vlist_at(&clients, i); - struct mqtt *m = (struct mqtt *) node->_vd; + struct vnode *n = (struct vnode *) vlist_at(&clients, i); + struct mqtt *m = (struct mqtt *) n->_vd; // Execute mosquitto loop for this client ret = mosquitto_loop(m->client, 0, 1); if (ret) { - warning("MQTT: connection error for node %s: %s, attempting reconnect", node_name(node), mosquitto_strerror(ret)); + n->logger->warn("Connection error: {}, attempting reconnect", mosquitto_strerror(ret)); ret = mosquitto_reconnect(m->client); if (ret != MOSQ_ERR_SUCCESS) - warning("MQTT: reconnection to broker failed for node %s: %s", node_name(node), mosquitto_strerror(ret)); + n->logger->warn("Reconnection to broker failed: {}", mosquitto_strerror(ret)); else - warning("MQTT: successfully reconnected to broker for node %s: %s", node_name(node), mosquitto_strerror(ret)); + n->logger->warn("Successfully reconnected to broker: {}", mosquitto_strerror(ret)); ret = mosquitto_loop(m->client, 0, 1); if (ret != MOSQ_ERR_SUCCESS) - warning("MQTT: persisting connection error for node %s: %s", node_name(node), mosquitto_strerror(ret)); + n->logger->warn("Persisting connection error: {}", mosquitto_strerror(ret)); } } } @@ -72,94 +72,96 @@ static void * mosquitto_loop_thread(void *ctx) return nullptr; } -static void mqtt_log_cb(struct mosquitto *mosq, void *userdata, int level, const char *str) +static void mqtt_log_cb(struct mosquitto *mosq, void *ctx, int level, const char *str) { + struct vnode *n = (struct vnode *) ctx; + switch (level) { case MOSQ_LOG_NONE: case MOSQ_LOG_INFO: case MOSQ_LOG_NOTICE: - info("MQTT: %s", str); + n->logger->info("{}", str); break; case MOSQ_LOG_WARNING: - warning("MQTT: %s", str); + n->logger->warn("{}", str); break; case MOSQ_LOG_ERR: - error("MQTT: %s", str); + n->logger->error("{}", str); break; case MOSQ_LOG_DEBUG: - debug(5, "MQTT: %s", str); + n->logger->debug("{}", str); break; } } -static void mqtt_connect_cb(struct mosquitto *mosq, void *userdata, int result) +static void mqtt_connect_cb(struct mosquitto *mosq, void *ctx, int result) { - struct vnode *n = (struct vnode *) userdata; + struct vnode *n = (struct vnode *) ctx; struct mqtt *m = (struct mqtt *) n->_vd; int ret; - info("MQTT: Node %s connected to broker %s", node_name(n), m->host); + n->logger->info("Connected to broker {}", m->host); if (m->subscribe) { ret = mosquitto_subscribe(m->client, nullptr, m->subscribe, m->qos); if (ret) - warning("MQTT: failed to subscribe to topic '%s' for node %s: %s", m->subscribe, node_name(n), mosquitto_strerror(ret)); + n->logger->warn("Failed to subscribe to topic '{}': {}", m->subscribe, mosquitto_strerror(ret)); } else - warning("MQTT: no subscribe for node %s as no subscribe topic is given", node_name(n)); + n->logger->warn("No subscription as no topic is configured"); } -static void mqtt_disconnect_cb(struct mosquitto *mosq, void *userdata, int result) +static void mqtt_disconnect_cb(struct mosquitto *mosq, void *ctx, int result) { - struct vnode *n = (struct vnode *) userdata; + struct vnode *n = (struct vnode *) ctx; struct mqtt *m = (struct mqtt *) n->_vd; - info("MQTT: Node %s disconnected from broker %s", node_name(n), m->host); + n->logger->info("Disconnected from broker {}", m->host); } -static void mqtt_message_cb(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *msg) +static void mqtt_message_cb(struct mosquitto *mosq, void *ctx, const struct mosquitto_message *msg) { int ret; - struct vnode *n = (struct vnode *) userdata; + struct vnode *n = (struct vnode *) ctx; struct mqtt *m = (struct mqtt *) n->_vd; struct sample *smps[n->in.vectorize]; - debug(5, "MQTT: Node %s received a message of %d bytes from broker %s", node_name(n), msg->payloadlen, m->host); + n->logger->debug("Received a message of {} bytes from broker {}", msg->payloadlen, m->host); ret = sample_alloc_many(&m->pool, smps, n->in.vectorize); if (ret <= 0) { - warning("Pool underrun in subscriber of %s", node_name(n)); + n->logger->warn("Pool underrun in subscriber"); return; } ret = io_sscan(&m->io, (char *) msg->payload, msg->payloadlen, nullptr, smps, n->in.vectorize); if (ret < 0) { - warning("MQTT: Node %s received an invalid message", node_name(n)); - warning(" Payload: %s", (char *) msg->payload); + n->logger->warn("Received an invalid message"); + n->logger->warn(" Payload: {}", (char *) msg->payload); return; } if (ret == 0) { - debug(4, "MQTT: skip empty message for node %s", node_name(n)); + n->logger->debug("Skip empty message"); sample_decref_many(smps, n->in.vectorize); return; } ret = queue_signalled_push_many(&m->queue, (void **) smps, n->in.vectorize); if (ret < (int) n->in.vectorize) - warning("MQTT: Failed to enqueue samples"); + n->logger->warn("Failed to enqueue samples"); } -static void mqtt_subscribe_cb(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos) +static void mqtt_subscribe_cb(struct mosquitto *mosq, void *ctx, int mid, int qos_count, const int *granted_qos) { - struct vnode *n = (struct vnode *) userdata; + struct vnode *n = (struct vnode *) ctx; struct mqtt *m = (struct mqtt *) n->_vd; - info("MQTT: Node %s subscribed to broker %s", node_name(n), m->host); + n->logger->info("Subscribed to broker {}", m->host); } int mqtt_reverse(struct vnode *n) @@ -212,12 +214,12 @@ int mqtt_init(struct vnode *n) return 0; mosquitto_error: - warning("MQTT: %s", mosquitto_strerror(ret)); + n->logger->warn("{}", mosquitto_strerror(ret)); return ret; } -int mqtt_parse(struct vnode *n, json_t *cfg) +int mqtt_parse(struct vnode *n, json_t *json) { int ret; struct mqtt *m = (struct mqtt *) n->_vd; @@ -232,7 +234,7 @@ int mqtt_parse(struct vnode *n, json_t *cfg) json_error_t err; json_t *json_ssl = nullptr; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: { s?: s }, s?: { s?: s }, s?: s, s: s, s?: i, s?: i, s?: i, s?: b, s?: s, s?: s, s?: o }", + ret = json_unpack_ex(json, &err, 0, "{ s?: { s?: s }, s?: { s?: s }, s?: s, s: s, s?: i, s?: i, s?: i, s?: b, s?: s, s?: s, s?: o }", "out", "publish", &publish, "in", @@ -248,7 +250,7 @@ int mqtt_parse(struct vnode *n, json_t *cfg) "ssl", &json_ssl ); if (ret) - throw ConfigError(cfg, err, "node-config-node-mqtt", "Failed to parse configuration of node {}", node_name(n)); + throw ConfigError(json, err, "node-config-node-mqtt"); m->host = strdup(host); m->publish = publish ? strdup(publish) : nullptr; @@ -257,7 +259,7 @@ int mqtt_parse(struct vnode *n, json_t *cfg) m->password = password ? strdup(password) : nullptr; if (!m->publish && !m->subscribe) - throw ConfigError(cfg, "node-config-node-mqtt", "At least one topic has to be specified for node {}", node_name(n)); + throw ConfigError(json, "node-config-node-mqtt", "At least one topic has to be specified for node {}", node_name(n)); if (json_ssl) { m->ssl.enabled = 1; @@ -301,11 +303,11 @@ int mqtt_check(struct vnode *n) ret = mosquitto_sub_topic_check(m->subscribe); if (ret != MOSQ_ERR_SUCCESS) - error("Invalid subscribe topic: '%s' for node %s: %s", m->subscribe, node_name(n), mosquitto_strerror(ret)); + throw RuntimeError("Invalid subscribe topic: '{}': {}", m->subscribe, mosquitto_strerror(ret)); ret = mosquitto_pub_topic_check(m->publish); if (ret != MOSQ_ERR_SUCCESS) - error("Invalid publish topic: '%s' for node %s: %s", m->publish, node_name(n), mosquitto_strerror(ret)); + throw RuntimeError("Invalid publish topic: '{}': {}", m->publish, mosquitto_strerror(ret)); return 0; } @@ -421,7 +423,7 @@ int mqtt_start(struct vnode *n) return 0; mosquitto_error: - warning("MQTT: %s", mosquitto_strerror(ret)); + n->logger->warn("{}", mosquitto_strerror(ret)); return ret; } @@ -443,7 +445,7 @@ int mqtt_stop(struct vnode *n) return 0; mosquitto_error: - warning("MQTT: %s", mosquitto_strerror(ret)); + n->logger->warn("{}", mosquitto_strerror(ret)); return ret; } @@ -452,6 +454,8 @@ int mqtt_type_start(villas::node::SuperNode *sn) { int ret; + logger = logging.get("node:mqtt"); + ret = vlist_init(&clients); if (ret) return ret; @@ -468,7 +472,7 @@ int mqtt_type_start(villas::node::SuperNode *sn) return 0; mosquitto_error: - warning("MQTT: %s", mosquitto_strerror(ret)); + logger->warn("{}", mosquitto_strerror(ret)); return ret; } @@ -481,7 +485,8 @@ int mqtt_type_stop() ret = pthread_cancel(thread); if (ret) return ret; - debug( 3, "Called pthread_cancel() on MQTT communication management thread."); + + logger->debug("Called pthread_cancel() on MQTT communication management thread."); ret = pthread_join(thread, nullptr); if (ret) @@ -493,7 +498,7 @@ int mqtt_type_stop() // When this is called the list of clients should be empty if (vlist_length(&clients) > 0) - error("List of MQTT clients contains elements at time of destruction. Call node_stop for each MQTT node before stopping node type!"); + throw RuntimeError("List of MQTT clients contains elements at time of destruction. Call node_stop for each MQTT node before stopping node type!"); ret = vlist_destroy(&clients, nullptr, false); if (ret) @@ -502,7 +507,7 @@ int mqtt_type_stop() return 0; mosquitto_error: - warning("MQTT: %s", mosquitto_strerror(ret)); + logger->warn("{}", mosquitto_strerror(ret)); return ret; } @@ -537,12 +542,12 @@ int mqtt_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *r if (m->publish) { ret = mosquitto_publish(m->client, nullptr /* mid */, m->publish, wbytes, data, m->qos, m->retain); if (ret != MOSQ_ERR_SUCCESS) { - warning("MQTT: publish failed for node %s: %s", node_name(n), mosquitto_strerror(ret)); + n->logger->warn("Publish failed: {}", mosquitto_strerror(ret)); return -abs(ret); } } else - warning("MQTT: no publish for node %s possible because no publish topic is given", node_name(n)); + n->logger->warn("No publish possible because no publish topic is configured"); return cnt; } diff --git a/lib/nodes/nanomsg.cpp b/lib/nodes/nanomsg.cpp index 9cd1b29d9..a4f38e366 100644 --- a/lib/nodes/nanomsg.cpp +++ b/lib/nodes/nanomsg.cpp @@ -28,7 +28,9 @@ #include #include #include +#include +using namespace villas; using namespace villas::utils; int nanomsg_reverse(struct vnode *n) @@ -48,16 +50,16 @@ int nanomsg_reverse(struct vnode *n) return 0; } -static int nanomsg_parse_endpoints(struct vlist *l, json_t *cfg) +static int nanomsg_parse_endpoints(struct vlist *l, json_t *json) { const char *ep; size_t i; json_t *json_val; - switch (json_typeof(cfg)) { + switch (json_typeof(json)) { case JSON_ARRAY: - json_array_foreach(cfg, i, json_val) { + json_array_foreach(json, i, json_val) { ep = json_string_value(json_val); if (!ep) return -1; @@ -67,7 +69,7 @@ static int nanomsg_parse_endpoints(struct vlist *l, json_t *cfg) break; case JSON_STRING: - ep = json_string_value(cfg); + ep = json_string_value(json); vlist_push(l, strdup(ep)); break; @@ -79,7 +81,7 @@ static int nanomsg_parse_endpoints(struct vlist *l, json_t *cfg) return 0; } -int nanomsg_parse(struct vnode *n, json_t *cfg) +int nanomsg_parse(struct vnode *n, json_t *json) { int ret; struct nanomsg *m = (struct nanomsg *) n->_vd; @@ -99,7 +101,7 @@ int nanomsg_parse(struct vnode *n, json_t *cfg) if (ret) return ret; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: { s?: o }, s?: { s?: o } }", + ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: { s?: o }, s?: { s?: o } }", "format", &format, "out", "endpoints", &json_out_endpoints, @@ -107,23 +109,23 @@ int nanomsg_parse(struct vnode *n, json_t *cfg) "endpoints", &json_in_endpoints ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-nanomsg"); if (json_out_endpoints) { ret = nanomsg_parse_endpoints(&m->out.endpoints, json_out_endpoints); if (ret < 0) - error("Invalid type for 'publish' setting of node %s", node_name(n)); + throw RuntimeError("Invalid type for 'publish' setting"); } if (json_in_endpoints) { ret = nanomsg_parse_endpoints(&m->in.endpoints, json_in_endpoints); if (ret < 0) - error("Invalid type for 'subscribe' setting of node %s", node_name(n)); + throw RuntimeError("Invalid type for 'subscribe' setting"); } m->format = format_type_lookup(format); if (!m->format) - error("Invalid format '%s' for node %s", format, node_name(n)); + throw RuntimeError("Invalid format '{}'", format); return 0; } @@ -165,16 +167,12 @@ int nanomsg_start(struct vnode *n) return ret; ret = m->in.socket = nn_socket(AF_SP, NN_SUB); - if (ret < 0) { - warning("Failed to create nanomsg socket: node=%s, error=%s", node_name(n), nn_strerror(errno)); - return ret; - } + if (ret < 0) + throw RuntimeError("Failed to create nanomsg socket: {}", nn_strerror(errno)); ret = m->out.socket = nn_socket(AF_SP, NN_PUB); - if (ret < 0) { - warning("Failed to create nanomsg socket: node=%s, error=%s", node_name(n), nn_strerror(errno)); - return ret; - } + if (ret < 0) + throw RuntimeError("Failed to create nanomsg socket: {}", nn_strerror(errno)); /* Subscribe to all topics */ ret = nn_setsockopt(ret = m->in.socket, NN_SUB, NN_SUB_SUBSCRIBE, "", 0); @@ -186,10 +184,8 @@ int nanomsg_start(struct vnode *n) char *ep = (char *) vlist_at(&m->out.endpoints, i); ret = nn_bind(m->out.socket, ep); - if (ret < 0) { - warning("Failed to connect nanomsg socket: node=%s, endpoint=%s, error=%s", node_name(n), ep, nn_strerror(errno)); - return ret; - } + if (ret < 0) + throw RuntimeError("Failed to connect nanomsg socket to endpoint {}: {}", ep, nn_strerror(errno)); } /* Connect subscribers socket */ @@ -197,10 +193,8 @@ int nanomsg_start(struct vnode *n) char *ep = (char *) vlist_at(&m->in.endpoints, i); ret = nn_connect(m->in.socket, ep); - if (ret < 0) { - warning("Failed to connect nanomsg socket: node=%s, endpoint=%s, error=%s", node_name(n), ep, nn_strerror(errno)); - return ret; - } + if (ret < 0) + throw RuntimeError("Failed to connect nanomsg socket to endpoint {}: {}", ep, nn_strerror(errno)); } return 0; diff --git a/lib/nodes/ngsi.cpp b/lib/nodes/ngsi.cpp index 2987d8e41..288d650f0 100644 --- a/lib/nodes/ngsi.cpp +++ b/lib/nodes/ngsi.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -54,8 +55,12 @@ static pthread_mutex_t *mutex_buf = NULL; void handle_error(const char *file, int lineno, const char *msg) { - error("** %s:%d %s\n", file, lineno, msg); + auto logger = logging.get("curl"); + + logger->error("** {}:{} {}", file, lineno, msg); + ERR_print_errors_fp(stderr); + /* exit(-1); */ } @@ -108,7 +113,7 @@ public: "value", &val ); if (ret) - throw ConfigError(json, "Failed to parse NGSI metadata"); + throw ConfigError(json, "node-config-node-ngsi-metadata", "Failed to parse NGSI metadata"); name = nam; type = typ; @@ -165,7 +170,7 @@ public: if (json_metadatas) { if (!json_is_array(json_metadatas)) - throw ConfigError(json_metadatas, "node-config-ngsi-metadata", "ngsi_metadata must be a list of objects"); + throw ConfigError(json_metadatas, "node-config-node-ngsi-metadata", "ngsi_metadata must be a list of objects"); json_t *json_metadata; json_array_foreach(json_metadatas, j, json_metadata) @@ -427,7 +432,7 @@ static int ngsi_parse_signals(json_t *json_signals, struct vlist *ngsi_signals, return 0; } -static int ngsi_parse_context_response(json_t *json_response, int *code, char **reason, json_t **json_rentity) { +static int ngsi_parse_context_response(json_t *json_response, int *code, char **reason, json_t **json_rentity, Logger logger) { int ret; char *codestr; @@ -441,14 +446,14 @@ static int ngsi_parse_context_response(json_t *json_response, int *code, char ** "reasonPhrase", reason ); if (ret) { - warning("Failed to find NGSI response code"); + logger->warn("Failed to find NGSI response code"); return ret; } *code = atoi(codestr); if (*code != 200) - warning("NGSI response: %s %s", codestr, *reason); + logger->warn("NGSI response: {} {}", codestr, *reason); return ret; } @@ -469,7 +474,7 @@ static size_t ngsi_request_writer(void *contents, size_t size, size_t nmemb, voi return realsize; } -static int ngsi_request(CURL *handle, const char *endpoint, const char *operation, json_t *json_request, json_t **json_response) +static int ngsi_request(CURL *handle, const char *endpoint, const char *operation, json_t *json_request, json_t **json_response, Logger logger) { struct ngsi_response chunk = { 0 }; char *post = json_dumps(json_request, JSON_INDENT(4)); @@ -486,7 +491,7 @@ static int ngsi_request(CURL *handle, const char *endpoint, const char *operatio curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE, strlen(post)); curl_easy_setopt(handle, CURLOPT_POSTFIELDS, post); - debug(LOG_NGSI | 18, "Request to context broker: %s\n%s", url, post); + logger->debug("Request to context broker: {}\n{}", url, post); /* We don't want to leave the handle in an invalid state */ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old); @@ -494,18 +499,18 @@ static int ngsi_request(CURL *handle, const char *endpoint, const char *operatio pthread_setcancelstate(old, nullptr); if (ret) { - warning("HTTP request failed: %s", curl_easy_strerror(ret)); + logger->warn("HTTP request failed: {}", curl_easy_strerror(ret)); goto out; } curl_easy_getinfo(handle, CURLINFO_TOTAL_TIME, &time); - debug(LOG_NGSI | 16, "Request to context broker completed in %.4f seconds", time); - debug(LOG_NGSI | 17, "Response from context broker:\n%s", chunk.data); + logger->debug("Request to context broker completed in {} seconds", time); + logger->debug("Response from context broker:\n{}", chunk.data); *json_response = json_loads(chunk.data, 0, &err); if (!*json_response) - warning("Received invalid JSON: %s in %s:%u:%u\n%s", err.text, err.source, err.line, err.column, chunk.data); + logger->warn("Received invalid JSON: {} in {}:{}:{}\n{}", err.text, err.source, err.line, err.column, chunk.data); out: free(post); free(chunk.data); @@ -513,7 +518,7 @@ out: free(post); return ret; } -static int ngsi_request_context_query(CURL *handle, const char *endpoint, json_t *json_entity, json_t **json_rentity) +static int ngsi_request_context_query(CURL *handle, const char *endpoint, json_t *json_entity, json_t **json_rentity, Logger logger) { int ret, code; char *reason; @@ -521,13 +526,13 @@ static int ngsi_request_context_query(CURL *handle, const char *endpoint, json_t json_t *json_response; json_t *json_request = json_pack("{ s: [ o ] }", "entities", json_entity); - ret = ngsi_request(handle, endpoint, "queryContext", json_request, &json_response); + ret = ngsi_request(handle, endpoint, "queryContext", json_request, &json_response, logger); if (ret) { ret = -1; goto out; } - ret = ngsi_parse_context_response(json_response, &code, &reason, json_rentity); + ret = ngsi_parse_context_response(json_response, &code, &reason, json_rentity, logger); if (ret) goto out2; @@ -537,7 +542,7 @@ out: json_decref(json_request); return ret; } -static int ngsi_request_context_update(CURL *handle, const char *endpoint, const char *action, json_t *json_entity) +static int ngsi_request_context_update(CURL *handle, const char *endpoint, const char *action, json_t *json_entity, Logger logger) { int ret, code; char *reason; @@ -548,12 +553,12 @@ static int ngsi_request_context_update(CURL *handle, const char *endpoint, const "contextElements", json_entity ); - ret = ngsi_request(handle, endpoint, "updateContext", json_request, &json_response); + ret = ngsi_request(handle, endpoint, "updateContext", json_request, &json_response, logger); if (ret) goto out; json_t *json_rentity; - ret = ngsi_parse_context_response(json_response, &code, &reason, &json_rentity); + ret = ngsi_parse_context_response(json_response, &code, &reason, &json_rentity, logger); if (ret) goto out2; @@ -577,7 +582,7 @@ int ngsi_type_start(villas::node::SuperNode *sn) CRYPTO_set_id_callback(curl_ssl_thread_id_function); CRYPTO_set_locking_callback(curl_ssl_locking_function); - info("Setup libcurl/openssl locking primitives"); + sn->getLogger()->info("Setup libcurl/openssl locking primitives"); #endif /* CURL_SSL_REQUIRES_LOCKING */ return curl_global_init(CURL_GLOBAL_ALL); @@ -603,7 +608,7 @@ int ngsi_type_stop() return 0; } -int ngsi_parse(struct vnode *n, json_t *cfg) +int ngsi_parse(struct vnode *n, json_t *json) { struct ngsi *i = (struct ngsi *) n->_vd; @@ -615,7 +620,7 @@ int ngsi_parse(struct vnode *n, json_t *cfg) int create = 1; int remove = 1; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s: s, s: s, s: s, s?: b, s?: F, s?: F, s?: b, s?: b, s?: { s?: o }, s?: { s?: o } }", + ret = json_unpack_ex(json, &err, 0, "{ s?: s, s: s, s: s, s: s, s?: b, s?: F, s?: F, s?: b, s?: b, s?: { s?: o }, s?: { s?: o } }", "access_token", &i->access_token, "endpoint", &i->endpoint, "entity_id", &i->entity_id, @@ -631,7 +636,7 @@ int ngsi_parse(struct vnode *n, json_t *cfg) "signals", &json_signals_out ); if (ret) - throw ConfigError(cfg, err, "node-config-node-ngsi", "Failed to parse configuration of node {}", node_name(n)); + throw ConfigError(json, err, "node-config-node-ngsi"); i->create = create; i->remove = remove; @@ -675,7 +680,7 @@ int ngsi_start(struct vnode *n) /* Create task */ if (i->timeout > 1 / i->rate) - warning("Timeout is to large for given rate: %f", i->rate); + n->logger->warn("Timeout is to large for given rate: {}", i->rate); i->task.setRate(i->rate); @@ -695,7 +700,7 @@ int ngsi_start(struct vnode *n) if (i->create) { json_t *json_entity = ngsi_build_entity(n, nullptr, 0, NGSI_ENTITY_ATTRIBUTES | NGSI_ENTITY_METADATA); - int ret = ngsi_request_context_update(i->out.curl, i->endpoint, "APPEND", json_entity); + int ret = ngsi_request_context_update(i->out.curl, i->endpoint, "APPEND", json_entity, n->logger); if (ret) throw RuntimeError("Failed to create NGSI context for node {}", node_name(n)); @@ -715,7 +720,7 @@ int ngsi_stop(struct vnode *n) /* Delete complete entity (not just attributes) */ json_t *json_entity = ngsi_build_entity(n, nullptr, 0, 0); - ret = ngsi_request_context_update(i->out.curl, i->endpoint, "DELETE", json_entity); + ret = ngsi_request_context_update(i->out.curl, i->endpoint, "DELETE", json_entity, n->logger); json_decref(json_entity); @@ -737,7 +742,7 @@ int ngsi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *re json_t *json_rentity; json_t *json_entity = ngsi_build_entity(n, nullptr, 0, 0); - ret = ngsi_request_context_query(i->in.curl, i->endpoint, json_entity, &json_rentity); + ret = ngsi_request_context_query(i->in.curl, i->endpoint, json_entity, &json_rentity, n->logger); if (ret) goto out; @@ -758,7 +763,7 @@ int ngsi_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *r json_t *json_entity = ngsi_build_entity(n, smps, cnt, NGSI_ENTITY_ATTRIBUTES_OUT | NGSI_ENTITY_VALUES); - ret = ngsi_request_context_update(i->out.curl, i->endpoint, "UPDATE", json_entity); + ret = ngsi_request_context_update(i->out.curl, i->endpoint, "UPDATE", json_entity, n->logger); json_decref(json_entity); diff --git a/lib/nodes/opal.cpp b/lib/nodes/opal.cpp index 4fb1aeaf0..bce879252 100644 --- a/lib/nodes/opal.cpp +++ b/lib/nodes/opal.cpp @@ -117,35 +117,34 @@ int opal_type_start(villas::node::SuperNode *sn) /* Enable the OpalPrint function. This prints to the OpalDisplay. */ err = OpalSystemCtrl_Register((char *) printShmemName.c_str()); if (err != EOK) - error("OpalPrint() access not available (%d)", err); + throw RuntimeError("OpalPrint() access not available ({})", err); /* Open Share Memory created by the model. */ err = OpalOpenAsyncMem(asyncShmemSize, asyncShmemName.c_str()); if (err != EOK) - error("Model shared memory not available (%d)", err); + throw RuntimeError("Model shared memory not available ({})", err); err = OpalGetAsyncCtrlParameters(¶ms, sizeof(Opal_GenAsyncParam_Ctrl)); if (err != EOK) - error("Could not get OPAL controller parameters (%d)", err); + throw RuntimeError("Could not get OPAL controller parameters ({})", err); /* Get list of Send and RecvIDs */ err = OpalGetNbAsyncSendIcon(&noSendIcons); if (err != EOK) - error("Failed to get number of send blocks (%d)", err); + throw RuntimeError("Failed to get number of send blocks ({})", err); err = OpalGetNbAsyncRecvIcon(&noRecvIcons); if (err != EOK) - error("Failed to get number of recv blocks (%d)", err); + throw RuntimeError("Failed to get number of recv blocks ({})", err); sendIDs.resize(noSendIcons); recvIDs.resize(noRecvIcons); err = OpalGetAsyncSendIDList(sendIDs.data(), noSendIcons * sizeof(int)); if (err != EOK) - error("Failed to get list of send ids (%d)", err); - + throw RuntimeError("Failed to get list of send ids ({})", err); err = OpalGetAsyncRecvIDList(recvIDs.data(), noRecvIcons * sizeof(int)); if (err != EOK) - error("Failed to get list of recv ids (%d)", err); + throw RuntimeError("Failed to get list of recv ids ({})", err); info("Started as OPAL Asynchronous process"); info("This is VILLASnode %s (built on %s, %s)", @@ -162,13 +161,14 @@ int opal_type_stop() err = OpalCloseAsyncMem(asyncShmemSize, asyncShmemName.c_str()); if (err != EOK) - error("Failed to close shared memory area (%d)", err); + throw RuntimeError("Failed to close shared memory area ({})", err); - debug(LOG_OPAL | 4, "Closing OPAL shared memory mapping"); + auto logger = logging.get("node:opal"); + logger->debug("Closing OPAL shared memory mapping"); err = OpalSystemCtrl_UnRegister((char *) printShmemName.c_str()); if (err != EOK) - error("Failed to close shared memory for system control (%d)", err); + throw RuntimeError("Failed to close shared memory for system control ({})", err); pthread_mutex_destroy(&lock); @@ -177,7 +177,8 @@ int opal_type_stop() int opal_print_global() { - debug(LOG_OPAL | 2, "Controller ID: %u", params.controllerID); + auto logger = logging.get("node:opal"); + logger->debug("Controller ID: {}", params.controllerID); std::stringstream sss, rss; @@ -186,34 +187,32 @@ int opal_print_global() for (auto i : recvIDs) rss << i << " "; - debug(LOG_OPAL | 2, "Send Blocks: %s", sss.str().c_str()); - debug(LOG_OPAL | 2, "Receive Blocks: %s", rss.str().c_str()); - - debug(LOG_OPAL | 2, "Control Block Parameters:"); + logger->debug("Send Blocks: {}", sss.str()); + logger->debug("Receive Blocks: {}", rss.str()); + logger->debug("Control Block Parameters:"); for (int i = 0; i < GENASYNC_NB_FLOAT_PARAM; i++) - debug(LOG_OPAL | 2, "FloatParam[]%u] = %f", i, params.FloatParam[i]); - + logger->debug("FloatParam[{}] = {}", i, params.FloatParam[i]); for (int i = 0; i < GENASYNC_NB_STRING_PARAM; i++) - debug(LOG_OPAL | 2, "StringParam[%u] = %s", i, params.StringParam[i]); + logger->debug("StringParam[{}] = {}", i, params.StringParam[i]); return 0; } -int opal_parse(struct vnode *n, json_t *cfg) +int opal_parse(struct vnode *n, json_t *json) { struct opal *o = (struct opal *) n->_vd; int ret; json_error_t err; - ret = json_unpack_ex(cfg, &err, 0, "{ s: i, s: i, s: b }", - "sendID", &o->sendID, - "recvID", &o->recvID, + ret = json_unpack_ex(json, &err, 0, "{ s: i, s: i, s: b }", + "send_id", &o->sendID, + "recv_id", &o->sendID, "reply", &o->reply ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-opal"); return 0; } @@ -240,9 +239,9 @@ int opal_start(struct vnode *n) rfound += i == o->sendID; if (!sfound) - error("Invalid sendID '%u' for node %s", o->sendID, node_name(n)); + throw RuntimeError("Invalid send_id '{}'", o->sendID); if (!rfound) - error("Invalid recvID '%u' for node %s", o->recvID, node_name(n)); + throw RuntimeError("Invalid recv_id '{}'", o->recvID); /* Get some more informations and paramters from OPAL-RT */ OpalGetAsyncSendIconMode(&o->mode, o->sendID); @@ -266,7 +265,7 @@ int opal_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *re double data[s->capacity]; if (cnt != 1) - error("The OPAL-RT node type does not support combining!"); + throw RuntimeError("The OPAL-RT node type does not support combining!"); /* This call unblocks when the 'Data Ready' line of a send icon is asserted. */ do { @@ -274,7 +273,7 @@ int opal_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *re if (ret != EOK) { state = OpalGetAsyncModelState(); if ((state == STATE_RESET) || (state == STATE_STOP)) - error("OpalGetAsyncModelState(): Model stopped or resetted!"); + throw RuntimeError("OpalGetAsyncModelState(): Model stopped or resetted!"); return -1; /* @todo correct return value */ } @@ -286,8 +285,8 @@ int opal_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *re /* Get the size of the data being sent by the unblocking SendID */ OpalGetAsyncSendIconDataLength(&len, o->sendID); if ((unsigned) len > s->capacity * sizeof(s->data[0])) { - warning("Ignoring the last %u of %u values for OPAL node %s (sendID=%u).", - len / sizeof(double) - s->capacity, len / sizeof(double), node_name(n), o->sendID); + n->logger->warn("Ignoring the last {} of {} values for OPAL (send_id={}).", + len / sizeof(double) - s->capacity, len / sizeof(double), o->send_id); len = sizeof(data); } @@ -314,7 +313,7 @@ int opal_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *re * has not been stopped. If it has, we quit. */ state = OpalGetAsyncModelState(); if ((state == STATE_RESET) || (state == STATE_STOP)) - error("OpalGetAsyncModelState(): Model stopped or resetted!"); + throw RuntimeError("OpalGetAsyncModelState(): Model stopped or resetted!"); return 1; } @@ -330,19 +329,19 @@ int opal_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *r double data[s->length]; if (cnt != 1) - error("The OPAL-RT node type does not support combining!"); + throw RuntimeError("The OPAL-RT node type does not support combining!"); state = OpalGetAsyncModelState(); if ((state == STATE_RESET) || (state == STATE_STOP)) - error("OpalGetAsyncModelState(): Model stopped or resetted!"); + throw RuntimeError("OpalGetAsyncModelState(): Model stopped or resetted!"); OpalSetAsyncRecvIconStatus(s->sequence, o->recvID); /* Set the Status to the message ID */ OpalSetAsyncRecvIconError(0, o->recvID); /* Set the Error to 0 */ /* Get the number of signals to send back to the model */ OpalGetAsyncRecvIconDataLength(&len, o->recvID); - if ((unsigned) len > sizeof(data)) - warning("Node %s is expecting more signals (%u) than values in message (%u)", node_name(n), len / sizeof(double), s->length); + if (len > sizeof(data)) + n->logger->warn("Node expecting more signals ({}) than values in message ({})", len / sizeof(double), s->length); for (unsigned i = 0; i < s->length; i++) data[i] = (double) s->data[i].f; /* OPAL expects double precission */ diff --git a/lib/nodes/rtp.cpp b/lib/nodes/rtp.cpp index 41940a050..2e1451a42 100644 --- a/lib/nodes/rtp.cpp +++ b/lib/nodes/rtp.cpp @@ -78,13 +78,13 @@ static int rtp_aimd(struct vnode *n, double loss_frac) if (r->aimd.rate_hook) { r->aimd.rate_hook->setRate(r->aimd.rate); - r->logger->debug("AIMD: Set rate limit to: {}", r->aimd.rate); + n->logger->debug("AIMD: Set rate limit to: {}", r->aimd.rate); } if (r->aimd.log) *(r->aimd.log) << r->rtcp.num_rrs << "\t" << loss_frac << "\t" << r->aimd.rate << std::endl; - r->logger->debug("AIMD: {}\t{}\t{}", r->rtcp.num_rrs, loss_frac, r->aimd.rate); + n->logger->debug("AIMD: {}\t{}\t{}", r->rtcp.num_rrs, loss_frac, r->aimd.rate); return 0; } @@ -93,7 +93,7 @@ int rtp_init(struct vnode *n) { struct rtp *r = (struct rtp *) n->_vd; - r->logger = villas::logging.get("node:rtp"); + n->logger = villas::logging.get("node:rtp"); /* Default values */ r->aimd.rate = 1; @@ -124,7 +124,7 @@ int rtp_reverse(struct vnode *n) return 0; } -int rtp_parse(struct vnode *n, json_t *cfg) +int rtp_parse(struct vnode *n, json_t *json) { int ret = 0; struct rtp *r = (struct rtp *) n->_vd; @@ -138,7 +138,7 @@ int rtp_parse(struct vnode *n, json_t *cfg) json_error_t err; json_t *json_aimd = nullptr; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: b, s?: o, s: { s: s }, s: { s: s } }", + ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: b, s?: o, s: { s: s }, s: { s: s } }", "format", &format, "rtcp", &r->rtcp.enabled, "aimd", &json_aimd, @@ -148,7 +148,7 @@ int rtp_parse(struct vnode *n, json_t *cfg) "address", &local ); if (ret) - r->logger->error("Failed to parse configuration of node {}", node_name(n)); + throw ConfigError(json, err, "node-config-node-rtp"); /* AIMD */ if (json_aimd) { @@ -165,7 +165,7 @@ int rtp_parse(struct vnode *n, json_t *cfg) "hook_type", &hook_type ); if (ret) - r->logger->error("Failed to parse configuration of node {}", node_name(n)); + throw ConfigError(json_aimd, err, "node-config-node-rtp-aimd"); /* AIMD Hook type */ if (!r->rtcp.enabled) @@ -178,7 +178,7 @@ int rtp_parse(struct vnode *n, json_t *cfg) else if (!strcmp(hook_type, "disabled")) r->aimd.rate_hook_type = RTPHookType::DISABLED; else - r->logger->error("Unknown RTCP hook_type: {}", hook_type); + throw RuntimeError("Unknown RTCP hook_type: {}", hook_type); } } @@ -188,14 +188,12 @@ int rtp_parse(struct vnode *n, json_t *cfg) /* Format */ r->format = format_type_lookup(format); if (!r->format) - r->logger->error("Invalid format '{}' for node {}", format, node_name(n)); + throw RuntimeError("Invalid format '{}'", format); /* Remote address */ ret = sa_decode(&r->out.saddr_rtp, remote, strlen(remote)); - if (ret) { - r->logger->error("Failed to resolve remote address '{}' of node {}: {}", - remote, node_name(n), strerror(ret)); - } + if (ret) + throw RuntimeError("Failed to resolve remote address '{}': {}", remote, strerror(ret)); /* Assign even port number to RTP socket, next odd number to RTCP socket */ port = sa_port(&r->out.saddr_rtp) & ~1; @@ -205,10 +203,8 @@ int rtp_parse(struct vnode *n, json_t *cfg) /* Local address */ ret = sa_decode(&r->in.saddr_rtp, local, strlen(local)); - if (ret) { - r->logger->error("Failed to resolve local address '{}' of node {}: {}", - local, node_name(n), strerror(ret)); - } + if (ret) + throw RuntimeError("Failed to resolve local address '{}': {}", local, strerror(ret)); /* Assign even port number to RTP socket, next odd number to RTCP socket */ port = sa_port(&r->in.saddr_rtp) & ~1; @@ -278,7 +274,7 @@ static void rtp_handler(const struct sa *src, const struct rtp_header *hdr, stru ret = queue_signalled_push(&r->recv_queue, d); if (ret != 1) { - r->logger->warn("Failed to push to queue"); + n->logger->warn("Failed to push to queue"); mem_deref(d); } } @@ -291,7 +287,7 @@ static void rtcp_handler(const struct sa *src, struct rtcp_msg *msg, void *arg) /* source not used */ (void) src; - debug(5, "RTCP: recv %s", rtcp_type_name((enum rtcp_type) msg->hdr.pt)); + n->logger->debug("RTCP: recv {}", rtcp_type_name((enum rtcp_type) msg->hdr.pt)); if (msg->hdr.pt == RTCP_SR) { if (msg->hdr.count > 0) { @@ -307,10 +303,10 @@ static void rtcp_handler(const struct sa *src, struct rtcp_msg *msg, void *arg) n->stats->update(Stats::Metric::RTP_JITTER, rr->jitter); } - r->logger->info("RTCP: rr: num_rrs={}, loss_frac={}, pkts_lost={}, jitter={}", r->rtcp.num_rrs, loss_frac, rr->lost, rr->jitter); + n->logger->info("RTCP: rr: num_rrs={}, loss_frac={}, pkts_lost={}, jitter={}", r->rtcp.num_rrs, loss_frac, rr->lost, rr->jitter); } else - debug(5, "RTCP: Received sender report with zero reception reports"); + n->logger->debug("RTCP: Received sender report with zero reception reports"); } r->rtcp.num_rrs++; @@ -365,7 +361,7 @@ int rtp_start(struct vnode *n) r->aimd.rate_hook->setRate(r->aimd.rate_last); #else - r->logger->error("Rate limiting is not supported"); + throw RuntimeError("Rate limiting is not supported"); return -1; #endif @@ -416,16 +412,12 @@ int rtp_stop(struct vnode *n) mem_deref(r->rs); ret = queue_signalled_close(&r->recv_queue); - if (ret) { - r->logger->error("Problem closing queue"); - return ret; - } + if (ret) + throw RuntimeError("Problem closing queue"); ret = queue_signalled_destroy(&r->recv_queue); - if (ret) { - r->logger->error("Problem destroying queue"); - return ret; - } + if (ret) + throw RuntimeError("Problem destroying queue"); mem_deref(r->send_mb); @@ -443,8 +435,6 @@ int rtp_destroy(struct vnode *n) { struct rtp *r = (struct rtp *) n->_vd; - //r->logger.~Logger(); - if (r->aimd.log) delete r->aimd.log; @@ -467,17 +457,13 @@ int rtp_type_start(villas::node::SuperNode *sn) /* Initialize library */ ret = libre_init(); - if (ret) { - error("Error initializing libre"); - return ret; - } + if (ret) + throw RuntimeError("Error initializing libre"); /* Add worker thread */ ret = pthread_create(&re_pthread, nullptr, (pthread_start_routine) re_main, nullptr); - if (ret) { - error("Error creating rtp node type pthread"); - return ret; - } + if (ret) + throw RuntimeError("Error creating rtp node type pthread"); struct sigaction sa; sa.sa_flags = SA_SIGINFO; @@ -494,10 +480,8 @@ int rtp_type_start(villas::node::SuperNode *sn) struct rtp *r = (struct rtp *) n->_vd; Interface *j = Interface::getEgress(&r->out.saddr_rtp.u.sa, sn); - if (!j) { - r->logger->error("Failed to find egress interface for node: {}", node_name(n)); - return -1; - } + if (!j) + throw RuntimeError("Failed to find egress interface"); j->addNode(n); } @@ -513,10 +497,8 @@ int rtp_type_stop() /* Join worker thread */ pthread_kill(re_pthread, SIGUSR1); ret = pthread_join(re_pthread, nullptr); - if (ret) { - error("Error joining rtp node type pthread"); - return ret; - } + if (ret) + throw RuntimeError("Error joining rtp node type pthread"); libre_close(); @@ -531,10 +513,8 @@ int rtp_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *rel /* Get data from queue */ ret = queue_signalled_pull(&r->recv_queue, (void **) &mb); - if (ret < 0) { - r->logger->error("Failed to pull from queue"); - return ret; - } + if (ret < 0) + throw RuntimeError("Failed to pull from queue"); /* Unpack data */ ret = io_sscan(&r->io, (char *) mb->buf + mb->pos, mbuf_get_left(mb), nullptr, smps, cnt); @@ -574,10 +554,8 @@ retry: mbuf_set_pos(r->send_mb, RTP_HEADER_SIZE); /* Send dataset */ ret = rtp_send(r->rs, &r->out.saddr_rtp, false, false, RTP_PACKET_TYPE, ts, r->send_mb); - if (ret) { - r->logger->error("Error from rtp_send, reason: {}", ret); - return ret; - } + if (ret) + throw RuntimeError("Error from rtp_send, reason: {}", ret); return cnt; } diff --git a/lib/nodes/shmem.cpp b/lib/nodes/shmem.cpp index 948722958..83e44f301 100644 --- a/lib/nodes/shmem.cpp +++ b/lib/nodes/shmem.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include #include @@ -40,7 +40,7 @@ using namespace villas; using namespace villas::utils; -int shmem_parse(struct vnode *n, json_t *cfg) +int shmem_parse(struct vnode *n, json_t *json) { struct shmem *shm = (struct shmem *) n->_vd; const char *val, *mode_str = nullptr; @@ -57,7 +57,7 @@ int shmem_parse(struct vnode *n, json_t *cfg) shm->conf.polling = false; shm->exec = nullptr; - ret = json_unpack_ex(cfg, &err, 0, "{ s: { s: s }, s: { s: s }, s?: i, s?: o, s?: s }", + ret = json_unpack_ex(json, &err, 0, "{ s: { s: s }, s: { s: s }, s?: i, s?: o, s?: s }", "out", "name", &shm->out_name, "in", @@ -67,7 +67,7 @@ int shmem_parse(struct vnode *n, json_t *cfg) "mode", &mode_str ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-shmem"); if (mode_str) { if (!strcmp(mode_str, "polling")) @@ -75,12 +75,12 @@ int shmem_parse(struct vnode *n, json_t *cfg) else if (!strcmp(mode_str, "pthread")) shm->conf.polling = false; else - error("Unknown mode '%s' in node %s", mode_str, node_name(n)); + throw SystemError("Unknown mode '{}'", mode_str); } if (json_exec) { if (!json_is_array(json_exec)) - error("Setting 'exec' of node %s must be an array of strings", node_name(n)); + throw SystemError("Setting 'exec' must be an array of strings"); shm->exec = new char*[json_array_size(json_exec) + 1]; if (!shm->exec) @@ -91,7 +91,7 @@ int shmem_parse(struct vnode *n, json_t *cfg) json_array_foreach(json_exec, i, json_val) { val = json_string_value(json_val); if (!val) - error("Setting 'exec' of node %s must be an array of strings", node_name(n)); + throw SystemError("Setting 'exec' must be an array of strings"); shm->exec[i] = strdup(val); } @@ -110,14 +110,14 @@ int shmem_start(struct vnode *n) if (shm->exec) { ret = spawn(shm->exec[0], shm->exec); if (!ret) - serror("Failed to spawn external program"); + throw SystemError("Failed to spawn external program"); sleep(1); } ret = shmem_int_open(shm->out_name, shm->in_name, &shm->intf, &shm->conf); if (ret < 0) - serror("Opening shared memory interface failed (%d)", ret); + throw SystemError("Opening shared memory interface failed (ret={})", ret); return 0; } @@ -143,7 +143,7 @@ int shmem_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *r /* This can only really mean that the other process has exited, so close * the interface to make sure the shared memory object is unlinked */ - info("Shared memory segment has been closed."); + n->logger->info("Shared memory segment has been closed."); n->state = State::STOPPING; @@ -168,15 +168,15 @@ int shmem_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * avail = sample_alloc_many(&shm->intf.write.shared->pool, shared_smps, cnt); if (avail != (int) cnt) - warning("Pool underrun for shmem node %s", shm->out_name); + n->logger->warn("Pool underrun for shmem node {}", shm->out_name); copied = sample_copy_many(shared_smps, smps, avail); if (copied < avail) - warning("Outgoing pool underrun for node %s", node_name(n)); + n->logger->warn("Outgoing pool underrun"); pushed = shmem_int_write(&shm->intf, shared_smps, copied); if (pushed != avail) - warning("Outgoing queue overrun for node %s", node_name(n)); + n->logger->warn("Outgoing queue overrun for node"); return pushed; } diff --git a/lib/nodes/signal_generator.cpp b/lib/nodes/signal_generator.cpp index 7bcdd89fd..25a33eba0 100644 --- a/lib/nodes/signal_generator.cpp +++ b/lib/nodes/signal_generator.cpp @@ -153,7 +153,7 @@ int signal_generator_prepare(struct vnode *n) return 0; } -int signal_generator_parse(struct vnode *n, json_t *cfg) +int signal_generator_parse(struct vnode *n, json_t *json) { struct signal_generator *s = (struct signal_generator *) n->_vd; @@ -171,7 +171,7 @@ int signal_generator_parse(struct vnode *n, json_t *cfg) json_t *json_pulse_low = nullptr; json_t *json_phase = nullptr; - ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s?: b, s?: i, s?: i, s?: F, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: b }", + ret = json_unpack_ex(json, &err, 0, "{ s: o, s?: b, s?: i, s?: i, s?: F, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: b }", "signal", &json_type, "realtime", &s->rt, "limit", &s->limit, @@ -188,7 +188,7 @@ int signal_generator_parse(struct vnode *n, json_t *cfg) "monitor_missed", &s->monitor_missed ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-signal"); struct desc { json_t *json; @@ -316,7 +316,7 @@ int signal_generator_stop(struct vnode *n) s->task.stop(); if (s->missed_steps > 0 && s->monitor_missed) - warning("Node %s missed a total of %d steps.", node_name(n), s->missed_steps); + n->logger->warn("Missed a total of {} steps.", s->missed_steps); delete[] s->last; @@ -396,7 +396,7 @@ int signal_generator_read(struct vnode *n, struct sample *smps[], unsigned cnt, } if (s->limit > 0 && s->counter >= (unsigned) s->limit) { - info("Node %s reached limit.", node_name(n)); + n->logger->info("Reached limit."); n->state = State::STOPPING; @@ -408,7 +408,7 @@ int signal_generator_read(struct vnode *n, struct sample *smps[], unsigned cnt, /* Block until 1/p->rate seconds elapsed */ steps = s->task.wait(); if (steps > 1 && s->monitor_missed) { - debug(5, "Missed steps: %u", steps-1); + n->logger->debug("Missed steps: {}", steps-1); s->missed_steps += steps-1; } } diff --git a/lib/nodes/socket.cpp b/lib/nodes/socket.cpp index 10fa6dceb..65c9cce85 100644 --- a/lib/nodes/socket.cpp +++ b/lib/nodes/socket.cpp @@ -129,30 +129,30 @@ int socket_check(struct vnode *n) /* Some checks on the addresses */ if (s->layer != SocketLayer::UNIX) { if (s->in.saddr.sa.sa_family != s->out.saddr.sa.sa_family) - error("Address families of local and remote must match!"); + throw RuntimeError("Address families of local and remote must match!"); } if (s->layer == SocketLayer::IP) { if (ntohs(s->in.saddr.sin.sin_port) != ntohs(s->out.saddr.sin.sin_port)) - error("IP protocol numbers of local and remote must match!"); + throw RuntimeError("IP protocol numbers of local and remote must match!"); } #ifdef WITH_SOCKET_LAYER_ETH else if (s->layer == SocketLayer::ETH) { if (ntohs(s->in.saddr.sll.sll_protocol) != ntohs(s->out.saddr.sll.sll_protocol)) - error("Ethertypes of local and remote must match!"); + throw RuntimeError("Ethertypes of local and remote must match!"); if (ntohs(s->in.saddr.sll.sll_protocol) <= 0x5DC) - error("Ethertype must be large than %d or it is interpreted as an IEEE802.3 length field!", 0x5DC); + throw RuntimeError("Ethertype must be large than {} or it is interpreted as an IEEE802.3 length field!", 0x5DC); } #endif /* WITH_SOCKET_LAYER_ETH */ if (s->multicast.enabled) { if (s->in.saddr.sa.sa_family != AF_INET) - error("Multicast is only supported by IPv4 for node %s", node_name(n)); + throw RuntimeError("Multicast is only supported by IPv4"); uint32_t addr = ntohl(s->multicast.mreq.imr_multiaddr.s_addr); if ((addr >> 28) != 14) - error("Multicast group address of node %s must be within 224.0.0.0/4", node_name(n)); + throw RuntimeError("Multicast group address must be within 224.0.0.0/4"); } return 0; @@ -189,11 +189,11 @@ int socket_start(struct vnode *n) break; default: - error("Invalid socket type!"); + throw RuntimeError("Invalid socket type!"); } if (s->sd < 0) - serror("Failed to create socket"); + throw SystemError("Failed to create socket"); /* Delete Unix domain socket if already existing */ if (s->layer == SocketLayer::UNIX) { @@ -228,20 +228,20 @@ int socket_start(struct vnode *n) ret = bind(s->sd, (struct sockaddr *) &s->in.saddr, addrlen); if (ret < 0) - serror("Failed to bind socket"); + throw SystemError("Failed to bind socket"); if (s->multicast.enabled) { ret = setsockopt(s->sd, IPPROTO_IP, IP_MULTICAST_LOOP, &s->multicast.loop, sizeof(s->multicast.loop)); if (ret) - serror("Failed to set multicast loop option"); + throw SystemError("Failed to set multicast loop option"); ret = setsockopt(s->sd, IPPROTO_IP, IP_MULTICAST_TTL, &s->multicast.ttl, sizeof(s->multicast.ttl)); if (ret) - serror("Failed to set multicast ttl option"); + throw SystemError("Failed to set multicast ttl option"); ret = setsockopt(s->sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &s->multicast.mreq, sizeof(s->multicast.mreq)); if (ret) - serror("Failed to join multicast group"); + throw SystemError("Failed to join multicast group"); } /* Set socket priority, QoS or TOS IP options */ @@ -251,18 +251,18 @@ int socket_start(struct vnode *n) case SocketLayer::IP: prio = IPTOS_LOWDELAY; if (setsockopt(s->sd, IPPROTO_IP, IP_TOS, &prio, sizeof(prio))) - serror("Failed to set type of service (QoS)"); + throw SystemError("Failed to set type of service (QoS)"); else - debug(LOG_SOCKET | 4, "Set QoS/TOS IP option for node %s to %#x", node_name(n), prio); + n->logger->debug("Set QoS/TOS IP option to {#x}", node_name(n), prio); break; default: #ifdef __linux__ prio = SOCKET_PRIO; if (setsockopt(s->sd, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio))) - serror("Failed to set socket priority"); + throw SystemError("Failed to set socket priority"); else - debug(LOG_SOCKET | 4, "Set socket priority for node %s to %d", node_name(n), prio); + n->logger->debug("Set socket priority to {}", prio); break; #else { } @@ -302,7 +302,7 @@ int socket_stop(struct vnode *n) if (s->multicast.enabled) { ret = setsockopt(s->sd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &s->multicast.mreq, sizeof(s->multicast.mreq)); if (ret) - serror("Failed to leave multicast group"); + throw SystemError("Failed to leave multicast group"); } if (s->sd >= 0) { @@ -336,7 +336,7 @@ int socket_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * /* Receive next sample */ bytes = recvfrom(s->sd, s->in.buf, s->in.buflen, 0, &src.sa, &srclen); if (bytes < 0) - serror("Failed recv from node %s", node_name(n)); + throw SystemError("Failed recvfrom()"); else if (bytes == 0) return 0; @@ -366,7 +366,7 @@ int socket_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * if (s->verify_source && socket_compare_addr(&src.sa, &s->out.saddr.sa) != 0) { char *buf = socket_print_addr((struct sockaddr *) &src); - warning("Received packet from unauthorized source: %s", buf); + n->logger->warn("Received packet from unauthorized source: {}", buf); free(buf); return 0; @@ -374,7 +374,7 @@ int socket_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned * ret = io_sscan(&s->io, ptr, bytes, &rbytes, smps, cnt); if (ret < 0 || (size_t) bytes != rbytes) - warning("Received invalid packet from node: %s ret=%d, bytes=%zu, rbytes=%zu", node_name(n), ret, bytes, rbytes); + n->logger->warn("Received invalid packet: ret={}, bytes={}, rbytes={}", ret, bytes, rbytes); return ret; } @@ -389,12 +389,12 @@ int socket_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned retry: ret = io_sprint(&s->io, s->out.buf, s->out.buflen, &wbytes, smps, cnt); if (ret < 0) { - warning("Failed to format payload: reason=%d", ret); + n->logger->warn("Failed to format payload: reason={}", ret); return ret; } if (wbytes == 0) { - warning("Failed to format payload: wbytes=%zu", wbytes); + n->logger->warn("Failed to format payload: wbytes={}", wbytes); return -1; } @@ -437,21 +437,21 @@ retry2: bytes = sendto(s->sd, s->out.buf, wbytes, 0, (struct sockaddr *) &s->out if (bytes < 0) { if ((errno == EPERM) || (errno == ENOENT && s->layer == SocketLayer::UNIX)) - warning("Failed send to node %s: %s", node_name(n), strerror(errno)); + n->logger->warn("Failed sendto(): {}", strerror(errno)); else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { - warning("socket: send would block"); + n->logger->warn("Blocking sendto()"); goto retry2; } else - warning("Failed sendto() to node %s", node_name(n)); + n->logger->warn("Failed sendto(): {}", strerror(errno)); } else if ((size_t) bytes < wbytes) - warning("Partial sendto() to node %s", node_name(n)); + n->logger->warn("Partial sendto()"); return cnt; } -int socket_parse(struct vnode *n, json_t *cfg) +int socket_parse(struct vnode *n, json_t *json) { struct socket *s = (struct socket *) n->_vd; @@ -468,7 +468,7 @@ int socket_parse(struct vnode *n, json_t *cfg) s->layer = SocketLayer::UDP; s->verify_source = 0; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: s, s: { s: s }, s: { s: s, s?: b, s?: o } }", + ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: s, s: { s: s }, s: { s: s, s?: b, s?: o } }", "layer", &layer, "format", &format, "out", @@ -479,12 +479,12 @@ int socket_parse(struct vnode *n, json_t *cfg) "multicast", &json_multicast ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-socket"); /* Format */ s->format = format_type_lookup(format); if (!s->format) - error("Invalid format '%s' for node %s", format, node_name(n)); + throw RuntimeError("Invalid format '{}'", format); /* IP layer */ if (layer) { @@ -499,20 +499,16 @@ int socket_parse(struct vnode *n, json_t *cfg) else if (!strcmp(layer, "unix") || !strcmp(layer, "local")) s->layer = SocketLayer::UNIX; else - error("Invalid layer '%s' for node %s", layer, node_name(n)); + throw SystemError("Invalid layer '{}'", layer); } ret = socket_parse_address(remote, (struct sockaddr *) &s->out.saddr, s->layer, 0); - if (ret) { - error("Failed to resolve remote address '%s' of node %s: %s", - remote, node_name(n), gai_strerror(ret)); - } + if (ret) + throw SystemError("Failed to resolve remote address '{}': {}", remote, gai_strerror(ret)); ret = socket_parse_address(local, (struct sockaddr *) &s->in.saddr, s->layer, AI_PASSIVE); - if (ret) { - error("Failed to resolve local address '%s' of node %s: %s", - local, node_name(n), gai_strerror(ret)); - } + if (ret) + throw SystemError("Failed to resolve local address '{}': {}", local, gai_strerror(ret)); if (json_multicast) { const char *group, *interface = nullptr; @@ -531,20 +527,16 @@ int socket_parse(struct vnode *n, json_t *cfg) "ttl", &s->multicast.ttl ); if (ret) - jerror(&err, "Failed to parse setting 'multicast' of node %s", node_name(n)); + throw ConfigError(json_multicast, err, "node-config-node-socket-multicast", "Failed to parse multicast settings"); ret = inet_aton(group, &s->multicast.mreq.imr_multiaddr); - if (!ret) { - error("Failed to resolve multicast group address '%s' of node %s", - group, node_name(n)); - } + if (!ret) + throw SystemError("Failed to resolve multicast group address '{}'", group); if (interface) { ret = inet_aton(group, &s->multicast.mreq.imr_interface); - if (!ret) { - error("Failed to resolve multicast interface address '%s' of node %s", - interface, node_name(n)); - } + if (!ret) + throw SystemError("Failed to resolve multicast interface address '{}'", interface); } } diff --git a/lib/nodes/stats.cpp b/lib/nodes/stats.cpp index 61e2353e4..0467ffc4d 100644 --- a/lib/nodes/stats.cpp +++ b/lib/nodes/stats.cpp @@ -43,7 +43,7 @@ int stats_node_signal_destroy(struct stats_node_signal *s) return 0; } -int stats_node_signal_parse(struct stats_node_signal *s, json_t *cfg) +int stats_node_signal_parse(struct stats_node_signal *s, json_t *json) { json_error_t err; @@ -51,11 +51,11 @@ int stats_node_signal_parse(struct stats_node_signal *s, json_t *cfg) const char *stats; char *metric, *type, *node, *cpy, *lasts; - ret = json_unpack_ex(cfg, &err, 0, "{ s: s }", + ret = json_unpack_ex(json, &err, 0, "{ s: s }", "stats", &stats ); if (ret) - return -1; + throw ConfigError(json, err, "node-config-node-stats"); cpy = strdup(stats); @@ -128,7 +128,7 @@ int stats_node_start(struct vnode *n) stats_sig->node = vlist_lookup_name(nodes, stats_sig->node_str); if (!stats_sig->node) - error("Invalid reference node %s for setting 'node' of node %s", stats_sig->node_str, node_name(n)); + throw ConfigError(n->config, "node-config-node-stats-node", "Invalid reference node {}", stats_sig->node_str); } return 0; @@ -178,7 +178,7 @@ int stats_node_destroy(struct vnode *n) return 0; } -int stats_node_parse(struct vnode *n, json_t *cfg) +int stats_node_parse(struct vnode *n, json_t *json) { struct stats_node *s = (struct stats_node *) n->_vd; @@ -187,19 +187,19 @@ int stats_node_parse(struct vnode *n, json_t *cfg) json_error_t err; json_t *json_signals, *json_signal; - ret = json_unpack_ex(cfg, &err, 0, "{ s: F, s: { s: o } }", + ret = json_unpack_ex(json, &err, 0, "{ s: F, s: { s: o } }", "rate", &s->rate, "in", "signals", &json_signals ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-stats"); if (s->rate <= 0) - error("Setting 'rate' of node %s must be positive", node_name(n)); + throw ConfigError(json, "node-config-node-stats-rate", "Setting 'rate' must be positive"); if (!json_is_array(json_signals)) - error("Setting 'in.signals' of node %s must be an array", node_name(n)); + throw ConfigError(json, "node-config-node-stats-in-signals", "Setting 'in.signals' must be an array"); json_array_foreach(json_signals, i, json_signal) { auto *stats_sig = new struct stats_node_signal; @@ -208,7 +208,7 @@ int stats_node_parse(struct vnode *n, json_t *cfg) ret = stats_node_signal_parse(stats_sig, json_signal); if (ret) - error("Failed to parse statistics signal definition of node %s", node_name(n)); + throw ConfigError(json_signal, "node-config-node-stats-signals", "Failed to parse statistics signal definition"); vlist_push(&s->signals, stats_sig); } diff --git a/lib/nodes/test_rtt.cpp b/lib/nodes/test_rtt.cpp index 728c5b357..96bb7472f 100644 --- a/lib/nodes/test_rtt.cpp +++ b/lib/nodes/test_rtt.cpp @@ -1,3 +1,4 @@ + /** Node type: Node-type for testing Round-trip Time. * * @author Steffen Vogel @@ -29,6 +30,7 @@ #include #include #include +#include #include using namespace villas; @@ -36,12 +38,13 @@ using namespace villas::utils; static struct plugin p; -static int test_rtt_case_start(struct test_rtt *t, int id) +static int test_rtt_case_start(struct vnode *n, int id) { int ret; + struct test_rtt *t = (struct test_rtt *) n->_vd; struct test_rtt_case *c = (struct test_rtt_case *) vlist_at(&t->cases, id); - info("Starting case #%d: filename=%s, rate=%f, values=%d, limit=%d", t->current, c->filename_formatted, c->rate, c->values, c->limit); + n->logger->info("Starting case #{}: filename={}, rate={}, values={}, limit={}", t->current, c->filename_formatted, c->rate, c->values, c->limit); /* Open file */ ret = io_open(&t->io, c->filename_formatted); @@ -57,9 +60,10 @@ static int test_rtt_case_start(struct test_rtt *t, int id) return 0; } -static int test_rtt_case_stop(struct test_rtt *t, int id) +static int test_rtt_case_stop(struct vnode *n, int id) { int ret; + struct test_rtt *t = (struct test_rtt *) n->_vd; /* Stop timer */ t->task.stop(); @@ -69,7 +73,7 @@ static int test_rtt_case_stop(struct test_rtt *t, int id) if (ret) return ret; - info("Stopping case #%d", id); + n->logger->info("Stopping case #{}", id); return 0; } @@ -117,7 +121,7 @@ int test_rtt_prepare(struct vnode *n) return 0; } -int test_rtt_parse(struct vnode *n, json_t *cfg) +int test_rtt_parse(struct vnode *n, json_t *json) { int ret; struct test_rtt *t = (struct test_rtt *) n->_vd; @@ -141,7 +145,7 @@ int test_rtt_parse(struct vnode *n, json_t *cfg) if (ret) return ret; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: s, s?: s, s?: F, s: o }", + ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: s, s?: s, s?: F, s: o }", "prefix", &prefix, "output", &output, "format", &format, @@ -149,7 +153,7 @@ int test_rtt_parse(struct vnode *n, json_t *cfg) "cases", &json_cases ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-test-rtt"); t->output = strdup(output); t->prefix = strdup(prefix); @@ -157,12 +161,12 @@ int test_rtt_parse(struct vnode *n, json_t *cfg) /* Initialize IO module */ t->format = format_type_lookup(format); if (!t->format) - error("Invalid value for setting 'format' of node %s", node_name(n)); + throw ConfigError(json, "node-config-node-test-rtt-format", "Invalid value for setting 'format'"); /* Construct vlist of test cases */ if (!json_is_array(json_cases)) - error("The 'cases' setting of node %s must be an array.", node_name(n)); + throw ConfigError(json_cases, "node-config-node-test-rtt-format", "The 'cases' setting must be an array."); json_array_foreach(json_cases, i, json_case) { int limit = -1; @@ -176,13 +180,13 @@ int test_rtt_parse(struct vnode *n, json_t *cfg) ); if (limit > 0 && duration > 0) - error("The settings 'duration' and 'limit' of node %s must be used exclusively", node_name(n)); + throw ConfigError(json_case, "node-config-node-test-rtt-duration", "The settings 'duration' and 'limit' must be used exclusively"); if (!json_is_array(json_rates) && !json_is_number(json_rates)) - error("The 'rates' setting of node %s must be a real or an array of real numbers", node_name(n)); + throw ConfigError(json_case, "node-config-node-test-rtt-rates", "The 'rates' setting must be a real or an array of real numbers"); if (!json_is_array(json_values) && !json_is_integer(json_values)) - error("The 'values' setting of node %s must be an integer or an array of integers", node_name(n)); + throw ConfigError(json_case, "node-config-node-test-rtt-values", "The 'values' setting must be an integer or an array of integers"); values.clear(); rates.clear(); @@ -191,7 +195,7 @@ int test_rtt_parse(struct vnode *n, json_t *cfg) size_t j; json_array_foreach(json_rates, j, json_val) { if (!json_is_number(json_val)) - error("The 'rates' setting of node %s must be an array of real numbers", node_name(n)); + throw ConfigError(json_val, "node-config-node-test-rtt-rates", "The 'rates' setting must be an array of real numbers"); rates.push_back(json_integer_value(json_val)); } @@ -203,7 +207,7 @@ int test_rtt_parse(struct vnode *n, json_t *cfg) size_t j; json_array_foreach(json_values, j, json_val) { if (!json_is_integer(json_val)) - error("The 'values' setting of node %s must be an array of integers", node_name(n)); + throw ConfigError(json_val, "node-config-node-test-rtt-values", "The 'values' setting must be an array of integers"); values.push_back(json_integer_value(json_val)); } @@ -219,6 +223,7 @@ int test_rtt_parse(struct vnode *n, json_t *cfg) c->filename = nullptr; c->filename_formatted = nullptr; + c->node = n; c->rate = rate; c->values = value; @@ -287,10 +292,8 @@ int test_rtt_start(struct vnode *n) ret = stat(t->output, &st); if (ret || !S_ISDIR(st.st_mode)) { ret = mkdir(t->output, 0777); - if (ret) { - warning("Failed to create output directory: %s", t->output); - return ret; - } + if (ret) + throw SystemError("Failed to create output directory: {}", t->output); } ret = io_init(&t->io, t->format, &n->in.signals, (int) SampleFlags::HAS_ALL & ~(int) SampleFlags::HAS_DATA); @@ -311,7 +314,7 @@ int test_rtt_stop(struct vnode *n) struct test_rtt *t = (struct test_rtt *) n->_vd; if (t->counter >= 0) { - ret = test_rtt_case_stop(t, t->current); + ret = test_rtt_case_stop(n, t->current); if (ret) return ret; } @@ -337,7 +340,7 @@ int test_rtt_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned t->current = 0; } else { - ret = test_rtt_case_stop(t, t->current); + ret = test_rtt_case_stop(n, t->current); if (ret) return ret; @@ -345,14 +348,14 @@ int test_rtt_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned } if ((unsigned) t->current >= vlist_length(&t->cases)) { - info("This was the last case. Stopping node %s", node_name(n)); + n->logger->info("This was the last case."); n->state = State::STOPPING; return -1; } else { - ret = test_rtt_case_start(t, t->current); + ret = test_rtt_case_start(n, t->current); if (ret) return ret; } @@ -363,15 +366,15 @@ int test_rtt_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned /* Wait */ steps = t->task.wait(); if (steps > 1) - warning("Skipped %ld steps", (long) (steps - 1)); + n->logger->warn("Skipped {} steps", steps - 1); if ((unsigned) t->counter >= c->limit) { - info("Stopping case #%d", t->current); + n->logger->info("Stopping case #{}", t->current); t->counter = -1; if (t->cooldown) { - info("Entering cooldown phase. Waiting %f seconds...", t->cooldown); + n->logger->info("Entering cooldown phase. Waiting {} seconds...", t->cooldown); t->task.setTimeout(t->cooldown); } @@ -407,7 +410,7 @@ int test_rtt_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigne unsigned i; for (i = 0; i < cnt; i++) { if (smps[i]->length != c->values) { - warning("Discarding invalid sample due to mismatching length: expecting=%d, has=%d", c->values, smps[i]->length); + n->logger->warn("Discarding invalid sample due to mismatching length: expecting={}, has={}", c->values, smps[i]->length); continue; } diff --git a/lib/nodes/uldaq.cpp b/lib/nodes/uldaq.cpp index b73466e11..015121620 100644 --- a/lib/nodes/uldaq.cpp +++ b/lib/nodes/uldaq.cpp @@ -182,19 +182,15 @@ static int uldaq_connect(struct vnode *n) /* Find Matching device */ if (!u->device_descriptor) { u->device_descriptor = uldaq_find_device(u); - if (!u->device_descriptor) { - warning("Unable to find a matching device for node '%s'", node_name(n)); - return -1; - } + if (!u->device_descriptor) + throw RuntimeError("Unable to find a matching device"); } /* Get a handle to the DAQ device associated with the first descriptor */ if (!u->device_handle) { u->device_handle = ulCreateDaqDevice(*u->device_descriptor); - if (!u->device_handle) { - warning("Unable to create handle for DAQ device for node '%s'", node_name(n)); - return -1; - } + if (!u->device_handle) + throw RuntimeError("Unable to create handle for DAQ device"); } /* Check if device is already connected */ @@ -209,8 +205,7 @@ static int uldaq_connect(struct vnode *n) if (err != ERR_NO_ERROR) { char buf[ERR_MSG_LEN]; ulGetErrMsg(err, buf); - warning("Failed to connect to DAQ device for node '%s': %s", node_name(n), buf); - return -1; + throw RuntimeError("Failed to connect to DAQ device: {}", buf); } } @@ -223,16 +218,15 @@ int uldaq_type_start(villas::node::SuperNode *sn) /* Get descriptors for all of the available DAQ devices */ err = ulGetDaqDeviceInventory(ANY_IFC, descriptors, &num_devs); - if (err != ERR_NO_ERROR) { - warning("Failed to retrieve DAQ device list"); - return -1; - } + if (err != ERR_NO_ERROR) + throw RuntimeError("Failed to retrieve DAQ device list"); - info("Found %d DAQ devices", num_devs); + auto logger = logging.get("node:uldaq"); + logger->info("Found {} DAQ devices", num_devs); for (unsigned i = 0; i < num_devs; i++) { DaqDeviceDescriptor *desc = &descriptors[i]; - info(" %d: %s %s (%s)", i, desc->uniqueId, desc->devString, uldaq_print_interface_type(desc->devInterface)); + logger->info(" {}: {} {} ({})", i, desc->uniqueId, desc->devString, uldaq_print_interface_type(desc->devInterface)); } return 0; @@ -281,7 +275,7 @@ int uldaq_destroy(struct vnode *n) return 0; } -int uldaq_parse(struct vnode *n, json_t *cfg) +int uldaq_parse(struct vnode *n, json_t *json) { int ret; struct uldaq *u = (struct uldaq *) n->_vd; @@ -295,7 +289,7 @@ int uldaq_parse(struct vnode *n, json_t *cfg) json_t *json_signal; json_error_t err; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: s, s: { s: o, s: F, s?: s, s?: s } }", + ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: s, s: { s: o, s: F, s?: s, s?: s } }", "interface_type", &interface_type, "device_id", &u->device_id, "in", @@ -305,12 +299,12 @@ int uldaq_parse(struct vnode *n, json_t *cfg) "input_mode", &default_input_mode_str ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-uldaq"); if (interface_type) { int iftype = uldaq_parse_interface_type(interface_type); if (iftype < 0) - error("Invalid interface type: %s for node '%s'", interface_type, node_name(n)); + throw ConfigError(json, "node-config-node-uldaq-interface-type", "Invalid interface type: {}", interface_type); u->device_interface_type = (DaqDeviceInterface) iftype; } @@ -333,7 +327,7 @@ int uldaq_parse(struct vnode *n, json_t *cfg) "channel", &channel ); if (ret) - jerror(&err, "Failed to parse signal configuration of node %s", node_name(n)); + throw ConfigError(json_signal, err, "node-config-node-uldaq-signal", "Failed to parse signal configuration"); if (!range_str) range_str = default_range_str; @@ -345,18 +339,18 @@ int uldaq_parse(struct vnode *n, json_t *cfg) channel = i; if (!range_str) - error("No input range specified for signal %zu of node %s.", i, node_name(n)); + throw ConfigError(json_signal, err, "node-config-node-uldaq-signal", "No input range specified for signal {}.", i); if (!input_mode_str) - error("No input mode specified for signal %zu of node %s.", i, node_name(n)); + throw ConfigError(json_signal, err, "node-config-node-uldaq-signal", "No input mode specified for signal {}.", i); range = uldaq_parse_range(range_str); if (range < 0) - error("Invalid input range specified for signal %zu of node %s.", i, node_name(n)); + throw ConfigError(json_signal, err, "node-config-node-uldaq-signal", "Invalid input range specified for signal {}.", i); input_mode = uldaq_parse_input_mode(input_mode_str); if (input_mode < 0) - error("Invalid input mode specified for signal %zu of node %s.", i, node_name(n)); + throw ConfigError(json_signal, err, "node-config-node-uldaq-signal", "Invalid input mode specified for signal {}.", i); u->in.queues[i].range = (Range) range; u->in.queues[i].inputMode = (AiInputMode) input_mode; @@ -399,10 +393,8 @@ int uldaq_check(struct vnode *n) UlError err; - if (n->in.vectorize < 100) { - warning("vectorize setting of node '%s' must be larger than 100", node_name(n)); - return -1; - } + if (n->in.vectorize < 100) + throw ConfigError(n->config, "node-config-node-vectorize", "Setting 'vectorize' must be larger than 100"); ret = uldaq_connect(n); if (ret) @@ -447,29 +439,21 @@ int uldaq_check(struct vnode *n) return -1; } - if (!has_ai) { - warning("DAQ device has no analog input channels"); - return -1; - } + if (!has_ai) + throw RuntimeError("DAQ device has no analog input channels"); - if (!(event_types & DE_ON_DATA_AVAILABLE)) { - warning("DAQ device does not support events"); - return -1; - } + if (!(event_types & DE_ON_DATA_AVAILABLE)) + throw RuntimeError("DAQ device does not support events"); - if ((scan_options & u->in.scan_options) != u->in.scan_options) { - warning("DAQ device does not support required scan options"); - return -1; - } + if ((scan_options & u->in.scan_options) != u->in.scan_options) + throw RuntimeError("DAQ device does not support required scan options"); for (size_t i = 0; i < vlist_length(&n->in.signals); i++) { struct signal *s = (struct signal *) vlist_at(&n->in.signals, i); AiQueueElement *q = &u->in.queues[i]; - if (s->type != SignalType::FLOAT) { - warning("Node '%s' only supports signals of type = float!", node_name(n)); - return -1; - } + if (s->type != SignalType::FLOAT) + throw RuntimeError("Node supports only signals of type = float!"); switch (q->inputMode) { case AI_PSEUDO_DIFFERENTIAL: @@ -488,13 +472,10 @@ int uldaq_check(struct vnode *n) break; } - warning("Unsupported range for signal %zu", i); - return -1; + throw RuntimeError("Unsupported range for signal {}", i); -found: if (q->channel > max_channel) { - warning("DAQ device does not support more than %lld channels", max_channel); - return -1; - } +found: if (q->channel > max_channel) + throw RuntimeError("DAQ device does not support more than {} channels", max_channel); } return 0; @@ -510,7 +491,7 @@ void uldaq_data_available(DaqDeviceHandle device_handle, DaqEventType event_type UlError err; err = ulAInScanStatus(device_handle, &u->in.status, &u->in.transfer_status); if (err != ERR_NO_ERROR) - warning("Failed to retrieve scan status in event callback"); + n->logger->warn("Failed to retrieve scan status in event callback"); pthread_mutex_unlock(&u->in.mutex); @@ -539,22 +520,18 @@ int uldaq_start(struct vnode *n) return ret; err = ulAInLoadQueue(u->device_handle, u->in.queues, vlist_length(&n->in.signals)); - if (err != ERR_NO_ERROR) { - warning("Failed to load input queue to DAQ device for node '%s'", node_name(n)); - return -1; - } + if (err != ERR_NO_ERROR) + throw RuntimeError("Failed to load input queue to DAQ device"); /* Enable the event to be notified every time samples are available */ err = ulEnableEvent(u->device_handle, DE_ON_DATA_AVAILABLE, n->in.vectorize, uldaq_data_available, n); /* Start the acquisition */ err = ulAInScan(u->device_handle, 0, 0, (AiInputMode) 0, (Range) 0, u->in.buffer_len / u->in.channel_count, &u->in.sample_rate, u->in.scan_options, u->in.flags, u->in.buffer); - if (err != ERR_NO_ERROR) { char buf[ERR_MSG_LEN]; ulGetErrMsg(err, buf); - warning("Failed to start acquisition on DAQ device for node '%s': %s", node_name(n), buf); - return -1; + throw RuntimeError("Failed to start acquisition on DAQ device: {}", buf); } /* Get the initial status of the acquisition */ @@ -562,15 +539,13 @@ int uldaq_start(struct vnode *n) if (err != ERR_NO_ERROR) { char buf[ERR_MSG_LEN]; ulGetErrMsg(err, buf); - warning("Failed to retrieve scan status on DAQ device for node '%s': %s", node_name(n), buf); - return -1; + throw RuntimeError("Failed to retrieve scan status on DAQ device: {}", buf); } if (u->in.status != SS_RUNNING) { char buf[ERR_MSG_LEN]; ulGetErrMsg(err, buf); - warning("Acquisition did not start on DAQ device for node '%s': %s", node_name(n), buf); - return -1; + throw RuntimeError("Acquisition did not start on DAQ device: {}", buf); } return 0; diff --git a/lib/nodes/websocket.cpp b/lib/nodes/websocket.cpp index d7918fa7f..ffd05c80b 100644 --- a/lib/nodes/websocket.cpp +++ b/lib/nodes/websocket.cpp @@ -45,6 +45,7 @@ using namespace villas::utils; static struct vlist connections; /**< List of active libwebsocket connections which receive samples from all nodes (catch all) */ static villas::node::Web *web; +static villas::Logger logger = logging.get("websocket"); /* Forward declarations */ static struct plugin p; @@ -148,11 +149,11 @@ static int websocket_connection_write(struct websocket_connection *c, struct sam pushed = queue_push_many(&c->queue, (void **) smps, cnt); if (pushed < (int) cnt) - warning("Queue overrun in WebSocket connection: %s", websocket_connection_name(c)); + c->node->logger->warn("Queue overrun in WebSocket connection: {}", websocket_connection_name(c)); sample_incref_many(smps, pushed); - debug(LOG_WEBSOCKET | 10, "Enqueued %u samples to %s", pushed, websocket_connection_name(c)); + c->node->logger->debug("Enqueued {} samples to {}", pushed, websocket_connection_name(c)); /* Client connections which are currently conecting don't have an associate c->wsi yet */ if (c->wsi) @@ -165,7 +166,7 @@ static void websocket_connection_close(struct websocket_connection *c, struct lw { lws_close_reason(wsi, status, (unsigned char *) reason, strlen(reason)); - debug(LOG_WEBSOCKET | 10, "Closing WebSocket connection with %s: status=%u, reason=%s", websocket_connection_name(c), status, reason); + c->node->logger->debug("Closing WebSocket connection with {}: status={}, reason={}", websocket_connection_name(c), status, reason); } int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) @@ -198,14 +199,16 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi lws_hdr_copy(wsi, uri, sizeof(uri), WSI_TOKEN_GET_URI); /* The path component of the*/ if (strlen(uri) <= 0) { websocket_connection_close(c, wsi, LWS_CLOSE_STATUS_PROTOCOL_ERR, "Invalid URL"); - warning("Failed to get request URI"); + + logger->warn("Failed to get request URI"); + return -1; } node = strtok_r(uri, "/.", &lasts); if (!node) { websocket_connection_close(c, wsi, LWS_CLOSE_STATUS_POLICY_VIOLATION, "Unknown node"); - warning("Failed to tokenize request URI"); + logger->warn("Failed to tokenize request URI"); return -1; } @@ -217,14 +220,14 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi c->node = vlist_lookup_name(&p.node.instances, node); if (!c->node) { websocket_connection_close(c, wsi, LWS_CLOSE_STATUS_POLICY_VIOLATION, "Unknown node"); - warning("Failed to find node: node=%s", node); + logger->warn("Failed to find node: {}", node); return -1; } c->format = format_type_lookup(format); if (!c->format) { websocket_connection_close(c, wsi, LWS_CLOSE_STATUS_POLICY_VIOLATION, "Unknown format"); - warning("Failed to find format: format=%s", format); + c->node->logger->warn("Failed to find format: format={}", format); return -1; } } @@ -232,25 +235,25 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi ret = websocket_connection_init(c); if (ret) { websocket_connection_close(c, wsi, LWS_CLOSE_STATUS_POLICY_VIOLATION, "Internal error"); - warning("Failed to intialize WebSocket connection: reason=%d", ret); + c->node->logger->warn("Failed to intialize WebSocket connection: reason={}", ret); return -1; } vlist_push(&connections, c); - info("Established WebSocket connection: %s", websocket_connection_name(c)); + c->node->logger->info("Established WebSocket connection: {}", websocket_connection_name(c)); break; case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: c->state = websocket_connection::State::ERROR; - warning("Failed to establish WebSocket connection: reason=%s", in ? (char *) in : "unknown"); + logger->warn("Failed to establish WebSocket connection: reason={}", in ? (char *) in : "unknown"); return -1; case LWS_CALLBACK_CLOSED: - debug(LOG_WEBSOCKET | 10, "Closed WebSocket connection: %s", websocket_connection_name(c)); + c->node->logger->debug("Closed WebSocket connection: {}", websocket_connection_name(c)); if (c->state != websocket_connection::State::SHUTDOWN) { /** @todo Attempt reconnect here */ @@ -283,7 +286,7 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi if (ret < 0) return ret; - debug(LOG_WEBSOCKET | 10, "Send %d samples to connection: %s, bytes=%d", pulled, websocket_connection_name(c), ret); + c->node->logger->debug("Send {} samples to connection: {}, bytes={}", pulled, websocket_connection_name(c), ret); } if (queue_available(&c->queue) > 0) @@ -314,15 +317,15 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi avail = sample_alloc_many(&w->pool, smps, cnt); if (avail < cnt) - warning("Pool underrun for connection: %s", websocket_connection_name(c)); + c->node->logger->warn("Pool underrun for connection: {}", websocket_connection_name(c)); recvd = io_sscan(&c->io, c->buffers.recv->data(), c->buffers.recv->size(), nullptr, smps, avail); if (recvd < 0) { - warning("Failed to parse sample data received on connection: %s", websocket_connection_name(c)); + c->node->logger->warn("Failed to parse sample data received on connection: {}", websocket_connection_name(c)); break; } - debug(LOG_WEBSOCKET | 10, "Received %d samples from connection: %s", recvd, websocket_connection_name(c)); + c->node->logger->debug("Received {} samples from connection: {}", recvd, websocket_connection_name(c)); /* Set receive timestamp */ for (int i = 0; i < recvd; i++) { @@ -332,7 +335,7 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi enqueued = queue_signalled_push_many(&w->queue, (void **) smps, recvd); if (enqueued < recvd) - warning("Queue overrun in connection: %s", websocket_connection_name(c)); + c->node->logger->warn("Queue overrun in connection: {}", websocket_connection_name(c)); /* Release unused samples back to pool */ if (enqueued < avail) @@ -440,7 +443,7 @@ int websocket_stop(struct vnode *n) } if (open_connections > 0) { - info("Waiting for shutdown of %u connections...", open_connections); + n->logger->info("Waiting for shutdown of {} connections...", open_connections); sleep(1); } @@ -498,7 +501,7 @@ int websocket_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsign /* Make copies of all samples */ avail = sample_alloc_many(&w->pool, cpys, cnt); if (avail < (int) cnt) - warning("Pool underrun for node %s: avail=%u", node_name(n), avail); + n->logger->warn("Pool underrun: avail={}", avail); sample_copy_many(cpys, smps, avail); @@ -514,7 +517,7 @@ int websocket_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsign return cnt; } -int websocket_parse(struct vnode *n, json_t *cfg) +int websocket_parse(struct vnode *n, json_t *json) { struct websocket *w = (struct websocket *) n->_vd; int ret; @@ -528,20 +531,20 @@ int websocket_parse(struct vnode *n, json_t *cfg) if (ret) return ret; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: o }", "destinations", &json_dests); + ret = json_unpack_ex(json, &err, 0, "{ s?: o }", "destinations", &json_dests); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-websocket"); if (json_dests) { if (!json_is_array(json_dests)) - error("The 'destinations' setting of node %s must be an array of URLs", node_name(n)); + throw ConfigError(json_dests, err, "node-config-node-websocket-destinations", "The 'destinations' setting must be an array of URLs"); json_array_foreach(json_dests, i, json_dest) { const char *uri, *prot, *ads, *path; uri = json_string_value(json_dest); if (!uri) - error("The 'destinations' setting of node %s must be an array of URLs", node_name(n)); + throw ConfigError(json_dest, err, "node-config-node-websocket-destinations", "The 'destinations' setting must be an array of URLs"); auto *d = new struct websocket_destination; if (!d) @@ -553,7 +556,7 @@ int websocket_parse(struct vnode *n, json_t *cfg) ret = lws_parse_uri(d->uri, &prot, &ads, &d->info.port, &path); if (ret) - error("Failed to parse WebSocket URI: '%s'", uri); + throw ConfigError(json_dest, err, "node-config-node-websocket-destinations", "Failed to parse WebSocket URI: '{}'", uri); d->info.ssl_connection = !strcmp(prot, "https"); d->info.address = strdup(ads); diff --git a/lib/nodes/zeromq.cpp b/lib/nodes/zeromq.cpp index e82c0e46f..899f3cf91 100644 --- a/lib/nodes/zeromq.cpp +++ b/lib/nodes/zeromq.cpp @@ -130,7 +130,7 @@ int zeromq_parse_endpoints(json_t *json_ep, struct vlist *epl) json_array_foreach(json_ep, i, json_val) { ep = json_string_value(json_val); if (!ep) - error("All 'publish' settings must be strings"); + throw ConfigError(json_val, "node-config-node-publish", "All 'publish' settings must be strings"); vlist_push(epl, strdup(ep)); } @@ -148,7 +148,7 @@ int zeromq_parse_endpoints(json_t *json_ep, struct vlist *epl) return 0; } -int zeromq_parse(struct vnode *n, json_t *cfg) +int zeromq_parse(struct vnode *n, json_t *json) { struct zeromq *z = (struct zeromq *) n->_vd; @@ -163,7 +163,7 @@ int zeromq_parse(struct vnode *n, json_t *cfg) json_t *json_curve = nullptr; json_error_t err; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: { s?: o, s?: s, s?: b }, s?: { s?: o, s?: s, s?: b }, s?: o, s?: s, s?: b, s?: s }", + ret = json_unpack_ex(json, &err, 0, "{ s?: { s?: o, s?: s, s?: b }, s?: { s?: o, s?: s, s?: b }, s?: o, s?: s, s?: b, s?: s }", "in", "subscribe", &json_in_ep, "filter", &in_filter, @@ -178,14 +178,14 @@ int zeromq_parse(struct vnode *n, json_t *cfg) "format", &format ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(json, err, "node-config-node-zeromq"); z->in.filter = in_filter ? strdup(in_filter) : nullptr; z->out.filter = out_filter ? strdup(out_filter) : nullptr; z->format = format_type_lookup(format); if (!z->format) - error("Invalid format '%s' for node %s", format, node_name(n)); + throw ConfigError(json, "node-config-node-zeromq-format", "Invalid format '{}'", format); if (json_out_ep) { ret = zeromq_parse_endpoints(json_out_ep, &z->out.endpoints); @@ -210,13 +210,13 @@ int zeromq_parse(struct vnode *n, json_t *cfg) "enabled", &z->curve.enabled ); if (ret) - jerror(&err, "Failed to parse setting 'curve' of node %s", node_name(n)); + throw ConfigError(json_curve, err, "node-config-node-zeromq-curve", "Failed to parse setting 'curve'"); if (strlen(secret_key) != 40) - error("Setting 'curve.secret_key' of node %s must be a Z85 encoded CurveZMQ key", node_name(n)); + throw ConfigError(json_curve, err, "node-config-node-zeromq-curve", "Setting 'curve.secret_key' must be a Z85 encoded CurveZMQ key"); if (strlen(public_key) != 40) - error("Setting 'curve.public_key' of node %s must be a Z85 encoded CurveZMQ key", node_name(n)); + throw ConfigError(json_curve, err, "node-config-node-zeromq-curve", "Setting 'curve.public_key' must be a Z85 encoded CurveZMQ key"); memcpy(z->curve.server.public_key, public_key, 41); memcpy(z->curve.server.secret_key, secret_key, 41); @@ -224,7 +224,7 @@ int zeromq_parse(struct vnode *n, json_t *cfg) /** @todo We should fix this. Its mostly done. */ if (z->curve.enabled) - error("CurveZMQ support is currently broken"); + throw ConfigError(json_curve, "node-config-zeromq-curve", "CurveZMQ support is currently broken"); if (type) { if (!strcmp(type, "pubsub")) @@ -234,7 +234,7 @@ int zeromq_parse(struct vnode *n, json_t *cfg) z->pattern = zeromq::Pattern::RADIODISH; #endif else - error("Invalid type for ZeroMQ node: %s", node_name_short(n)); + throw ConfigError(json, "node-config-node-zeromq-type", "Invalid type for ZeroMQ node: {}", node_name_short(n)); } return 0; @@ -470,7 +470,7 @@ int zeromq_start(struct vnode *n) #endif fail: - info("Failed to start ZeroMQ node: %s, error=%s", node_name(n), zmq_strerror(errno)); + n->logger->info("Failed to start: {}", zmq_strerror(errno)); return ret; } diff --git a/lib/path.cpp b/lib/path.cpp index 3cdd9efcd..a0a575cf6 100644 --- a/lib/path.cpp +++ b/lib/path.cpp @@ -98,7 +98,7 @@ static void * path_run_poll(void *arg) while (p->state == State::STARTED) { ret = poll(p->reader.pfds, p->reader.nfds, -1); if (ret < 0) - serror("Failed to poll"); + throw SystemError("Failed to poll"); p->logger->debug("Path {} returned from poll(2)", path_name(p)); @@ -379,14 +379,14 @@ int path_prepare(struct vpath *p, struct vlist *nodes) #endif /* WITH_HOOKS */ p->logger->info("Prepared path {} with output signals:", path_name(p)); - signal_list_dump(path_output_signals(p)); + signal_list_dump(p->logger, path_output_signals(p)); p->state = State::PREPARED; return 0; } -int path_parse(struct vpath *p, json_t *cfg, struct vlist *nodes, const uuid_t sn_uuid) +int path_parse(struct vpath *p, json_t *json, struct vlist *nodes, const uuid_t sn_uuid) { int ret; @@ -405,7 +405,7 @@ int path_parse(struct vpath *p, json_t *cfg, struct vlist *nodes, const uuid_t s if (ret) return ret; - ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s?: o, s?: o, s?: b, s?: b, s?: b, s?: i, s?: s, s?: b, s?: F, s?: o, s?: b, s?: s, s?: i }", + ret = json_unpack_ex(json, &err, 0, "{ s: o, s?: o, s?: o, s?: b, s?: b, s?: b, s?: i, s?: s, s?: b, s?: F, s?: o, s?: b, s?: s, s?: i }", "in", &json_in, "out", &json_out, "hooks", &json_hooks, @@ -422,7 +422,7 @@ int path_parse(struct vpath *p, json_t *cfg, struct vlist *nodes, const uuid_t s "affinity", &p->affinity ); if (ret) - throw ConfigError(cfg, err, "node-config-path", "Failed to parse path configuration"); + throw ConfigError(json, err, "node-config-path", "Failed to parse path configuration"); /* Optional settings */ if (mode) { @@ -431,18 +431,18 @@ int path_parse(struct vpath *p, json_t *cfg, struct vlist *nodes, const uuid_t s else if (!strcmp(mode, "all")) p->mode = PathMode::ALL; else - throw ConfigError(cfg, "node-config-path", "Invalid path mode '{}'", mode); + throw ConfigError(json, "node-config-path", "Invalid path mode '{}'", mode); } /* UUID */ if (uuid_str) { ret = uuid_parse(uuid_str, p->uuid); if (ret) - throw ConfigError(cfg, "node-config-path-uuid", "Failed to parse UUID: {}", uuid_str); + throw ConfigError(json, "node-config-path-uuid", "Failed to parse UUID: {}", uuid_str); } else /* Generate UUID from hashed config */ - uuid_generate_from_json(p->uuid, cfg, sn_uuid); + uuid_generate_from_json(p->uuid, json, sn_uuid); /* Input node(s) */ ret = mapping_list_parse(&p->mappings, json_in); @@ -460,7 +460,7 @@ int path_parse(struct vpath *p, json_t *cfg, struct vlist *nodes, const uuid_t s struct vnode *n = (struct vnode *) vlist_at(&destinations, i); if (n->output_path) - throw ConfigError(cfg, "node-config-path", "Every node must only be used by a single path as destination"); + throw ConfigError(json, "node-config-path", "Every node must only be used by a single path as destination"); n->output_path = p; @@ -488,7 +488,7 @@ int path_parse(struct vpath *p, json_t *cfg, struct vlist *nodes, const uuid_t s if (ret) return ret; - p->cfg = cfg; + p->config = json; p->state = State::PARSED; return 0; @@ -764,7 +764,7 @@ bool path_is_simple(const struct vpath *p) const char *in = nullptr, *out = nullptr; json_error_t err; - ret = json_unpack_ex(p->cfg, &err, 0, "{ s: s, s: s }", "in", &in, "out", &out); + ret = json_unpack_ex(p->config, &err, 0, "{ s: s, s: s }", "in", &in, "out", &out); if (ret) return false; diff --git a/lib/pool.cpp b/lib/pool.cpp index 8b1250bd5..81b432814 100644 --- a/lib/pool.cpp +++ b/lib/pool.cpp @@ -25,6 +25,7 @@ #include #include #include +#include using namespace villas; @@ -41,7 +42,8 @@ int pool_init(struct pool *p, size_t cnt, size_t blocksz, struct memory_type *m) if (!buffer) throw MemoryAllocationError(); - debug(LOG_POOL | 4, "Allocated %#zx bytes for memory pool", p->len); + auto logger = logging.get("pool"); + logger->debug("Allocated {#x} bytes for memory pool", p->len); p->buffer_off = (char*) buffer - (char*) p; diff --git a/lib/queue.cpp b/lib/queue.cpp index 43604f7cf..c08097e81 100644 --- a/lib/queue.cpp +++ b/lib/queue.cpp @@ -34,6 +34,9 @@ #include #include #include +#include + +using namespace villas; /** Initialize MPMC queue */ int queue_init(struct queue *q, size_t size, struct memory_type *m) @@ -42,7 +45,9 @@ int queue_init(struct queue *q, size_t size, struct memory_type *m) if (!IS_POW2(size)) { size_t old_size = size; size = LOG2_CEIL(size); - warning("A queue size was changed from %zu to %zu", old_size, size); + + auto logger = logging.get("queue"); + logger->warn("A queue size was changed from {} to {}", old_size, size); } q->buffer_mask = size - 1; diff --git a/lib/queue_signalled.cpp b/lib/queue_signalled.cpp index 5111ff7b1..6243b606a 100644 --- a/lib/queue_signalled.cpp +++ b/lib/queue_signalled.cpp @@ -23,7 +23,6 @@ #include #include -#include #ifdef HAS_EVENTFD #include diff --git a/lib/sample.cpp b/lib/sample.cpp index ac04f9672..3191692a2 100644 --- a/lib/sample.cpp +++ b/lib/sample.cpp @@ -290,24 +290,28 @@ enum SignalType sample_format(const struct sample *s, unsigned idx) return sig ? sig->type : SignalType::INVALID; } -void sample_dump(struct sample *s) +void sample_dump(Logger logger, struct sample *s) { - info("Sample: sequence=%" PRIu64 ", length=%d, capacity=%d, flags=%#x, signals=%p, #signals=%zu, " - "refcnt=%d, pool_off=%zd", - s->sequence, s->length, s->capacity, s->flags, s->signals, - s->signals ? vlist_length(s->signals) : 0, atomic_load(&s->refcnt), s->pool_off); + logger->info("Sample: sequence={}, length={}, capacity={}," + "flags={:#x}, #signals={}, " + "refcnt={}, pool_off={}", + s->sequence, + s->length, + s->capacity, + s->flags, + s->signals ? vlist_length(s->signals) : -1, + atomic_load(&s->refcnt), + s->pool_off); if (s->flags & (int) SampleFlags::HAS_TS_ORIGIN) - info(" ts.origin=%lld.%lld", (long long) s->ts.origin.tv_sec, - (long long) s->ts.origin.tv_nsec); + logger->info(" ts.origin={}.{:09f}", s->ts.origin.tv_sec, s->ts.origin.tv_nsec); if (s->flags & (int) SampleFlags::HAS_TS_RECEIVED) - info(" ts.received=%lld.%lld", (long long) s->ts.received.tv_sec, - (long long) s->ts.received.tv_nsec); + logger->info(" ts.received={}.{:09f}", s->ts.received.tv_sec, s->ts.received.tv_nsec); if (s->signals) { - info(" Signals:"); - signal_list_dump(s->signals, s->data, s->length); + logger->info(" Signals:"); + signal_list_dump(logger, s->signals, s->data, s->length); } } diff --git a/lib/signal.cpp b/lib/signal.cpp index fbbd6df88..7c151ca9a 100644 --- a/lib/signal.cpp +++ b/lib/signal.cpp @@ -187,7 +187,7 @@ struct signal * signal_copy(struct signal *s) return ns; } -int signal_parse(struct signal *s, json_t *cfg) +int signal_parse(struct signal *s, json_t *json) { int ret; json_error_t err; @@ -196,7 +196,7 @@ int signal_parse(struct signal *s, json_t *cfg) const char *unit = nullptr; const char *type = "float"; - ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: s, s?: s, s?: o, s?: b }", + ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: s, s?: s, s?: o, s?: b }", "name", &name, "unit", &unit, "type", &type, diff --git a/lib/signal_data.cpp b/lib/signal_data.cpp index bcb822bd9..2f490b324 100644 --- a/lib/signal_data.cpp +++ b/lib/signal_data.cpp @@ -197,28 +197,28 @@ int signal_data_parse_str(union signal_data *data, enum SignalType type, const c return 0; } -int signal_data_parse_json(union signal_data *data, enum SignalType type, json_t *cfg) +int signal_data_parse_json(union signal_data *data, enum SignalType type, json_t *json) { int ret; switch (type) { case SignalType::FLOAT: - data->f = json_real_value(cfg); + data->f = json_real_value(json); break; case SignalType::INTEGER: - data->i = json_integer_value(cfg); + data->i = json_integer_value(json); break; case SignalType::BOOLEAN: - data->b = json_boolean_value(cfg); + data->b = json_boolean_value(json); break; case SignalType::COMPLEX: { double real, imag; json_error_t err; - ret = json_unpack_ex(cfg, &err, 0, "{ s: F, s: F }", + ret = json_unpack_ex(json, &err, 0, "{ s: F, s: F }", "real", &real, "imag", &imag ); diff --git a/lib/signal_list.cpp b/lib/signal_list.cpp index 687be5cef..ce4aad6a0 100644 --- a/lib/signal_list.cpp +++ b/lib/signal_list.cpp @@ -66,17 +66,17 @@ int signal_list_destroy(struct vlist *list) return 0; } -int signal_list_parse(struct vlist *list, json_t *cfg) +int signal_list_parse(struct vlist *list, json_t *json) { int ret; struct signal *s; - if (!json_is_array(cfg)) + if (!json_is_array(json)) return -1; size_t i; json_t *json_signal; - json_array_foreach(cfg, i, json_signal) { + json_array_foreach(json, i, json_signal) { s = new struct signal; if (!s) throw MemoryAllocationError(); @@ -141,7 +141,7 @@ int signal_list_generate2(struct vlist *list, const char *dt) return 0; } -void signal_list_dump(const struct vlist *list, const union signal_data *data, unsigned len) +void signal_list_dump(Logger logger, const struct vlist *list, const union signal_data *data, unsigned len) { for (size_t i = 0; i < vlist_length(list); i++) { struct signal *sig = (struct signal *) vlist_at(list, i); @@ -164,7 +164,7 @@ void signal_list_dump(const struct vlist *list, const union signal_data *data, u strcatf(&buf, " = %s", val); } - debug(5, "%s", buf); + logger->debug("{}", buf); free(buf); } } diff --git a/lib/signal_type.cpp b/lib/signal_type.cpp index a39a9fa35..0e4da1c8b 100644 --- a/lib/signal_type.cpp +++ b/lib/signal_type.cpp @@ -22,7 +22,6 @@ #include -#include #include enum SignalType signal_type_from_str(const char *str) @@ -86,8 +85,6 @@ enum SignalType signal_type_detect(const char *val) const char *brk; int len; - debug(LOG_IO | 5, "Attempt to detect type of value: %s", val); - brk = strchr(val, 'i'); if (brk) return SignalType::COMPLEX; diff --git a/lib/socket_addr.cpp b/lib/socket_addr.cpp index b2995dbe3..3794e53ce 100644 --- a/lib/socket_addr.cpp +++ b/lib/socket_addr.cpp @@ -65,7 +65,7 @@ char * socket_print_addr(struct sockaddr *saddr) break; default: - error("Unknown address family: '%u'", sa->sa.sa_family); + throw RuntimeError("Unknown address family: '{}'", sa->sa.sa_family); } /* Port / Interface */ @@ -80,7 +80,7 @@ char * socket_print_addr(struct sockaddr *saddr) struct nl_cache *cache = nl_cache_mngt_require("route/link"); struct rtnl_link *link = rtnl_link_get(cache, sa->sll.sll_ifindex); if (!link) - error("Failed to get interface for index: %u", sa->sll.sll_ifindex); + throw RuntimeError("Failed to get interface for index: {}", sa->sll.sll_ifindex); strcatf(&buf, "%%%s", rtnl_link_get_name(link)); strcatf(&buf, ":%hu", ntohs(sa->sll.sll_protocol)); @@ -104,7 +104,7 @@ int socket_parse_address(const char *addr, struct sockaddr *saddr, enum SocketLa sa->sun.sun_family = AF_UNIX; if (strlen(addr) > sizeof(sa->sun.sun_path) - 1) - error("Length of unix socket path is too long!"); + throw RuntimeError("Length of unix socket path is too long!"); memcpy(sa->sun.sun_path, addr, strlen(addr) + 1); @@ -121,7 +121,7 @@ int socket_parse_address(const char *addr, struct sockaddr *saddr, enum SocketLa /* Parse link layer (MAC) address */ struct ether_addr *mac = ether_aton(node); if (!mac) - error("Failed to parse MAC address: %s", node); + throw RuntimeError("Failed to parse MAC address: {}", node); memcpy(&sa->sll.sll_addr, &mac->ether_addr_octet, ETHER_ADDR_LEN); @@ -131,7 +131,7 @@ int socket_parse_address(const char *addr, struct sockaddr *saddr, enum SocketLa struct nl_cache *cache = nl_cache_mngt_require("route/link"); struct rtnl_link *link = rtnl_link_get_by_name(cache, ifname); if (!link) - error("Failed to get network interface: '%s'", ifname); + throw RuntimeError("Failed to get network interface: '{}'", ifname); sa->sll.sll_protocol = htons(proto ? strtol(proto, nullptr, 0) : ETH_P_VILLAS); sa->sll.sll_halen = ETHER_ADDR_LEN; @@ -171,7 +171,7 @@ int socket_parse_address(const char *addr, struct sockaddr *saddr, enum SocketLa break; default: - error("Invalid address type"); + throw RuntimeError("Invalid address type"); } /* Lookup address */ diff --git a/lib/stats.cpp b/lib/stats.cpp index 48d8733de..bd79845b4 100644 --- a/lib/stats.cpp +++ b/lib/stats.cpp @@ -27,9 +27,7 @@ #include #include #include -#include #include -#include using namespace villas; using namespace villas::utils; @@ -102,7 +100,8 @@ enum Stats::Type Stats::lookupType(const std::string &str) throw std::invalid_argument("Invalid stats type"); } -Stats::Stats(int buckets, int warmup) +Stats::Stats(int buckets, int warmup) : + logger(logging.get("stats")) { for (auto m : metrics) { histograms.emplace( @@ -151,8 +150,10 @@ void Stats::printHeader(enum Format fmt) void Stats::setupTable() { - if (!table) - table = std::make_shared(columns); + if (!table) { + auto logger = logging.get("stats"); + table = std::make_shared
(logger, columns); + } } void Stats::printPeriodic(FILE *f, enum Format fmt, struct vnode *n) const @@ -202,8 +203,8 @@ void Stats::print(FILE *f, enum Format fmt, int verbose) const switch (fmt) { case Format::HUMAN: for (auto m : metrics) { - info("%s: %s", m.second.name, m.second.desc); - histograms.at(m.first).print(verbose); + logger->info("{}: {}", m.second.name, m.second.desc); + histograms.at(m.first).print(logger, verbose); } break; diff --git a/lib/super_node.cpp b/lib/super_node.cpp index dd88cd316..3118a43d4 100644 --- a/lib/super_node.cpp +++ b/lib/super_node.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -530,7 +529,7 @@ int SuperNode::periodic() } if (idleStop > 0 && state == State::STARTED && started == 0) { - info("No more active paths. Stopping super-node"); + logger->info("No more active paths. Stopping super-node"); return -1; } diff --git a/lib/web.cpp b/lib/web.cpp index 28aa79704..7e18fb570 100644 --- a/lib/web.cpp +++ b/lib/web.cpp @@ -189,7 +189,7 @@ Web::Web(Api *a) : lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE, lwsLogger); } -int Web::parse(json_t *cfg) +int Web::parse(json_t *json) { int ret, enabled = 1; const char *cert = nullptr; @@ -197,7 +197,7 @@ int Web::parse(json_t *cfg) const char *htd = nullptr; json_error_t err; - ret = json_unpack_ex(cfg, &err, JSON_STRICT, "{ s?: s, s?: s, s?: s, s?: i, s?: b }", + ret = json_unpack_ex(json, &err, JSON_STRICT, "{ s?: s, s?: s, s?: s, s?: i, s?: b }", "ssl_cert", &cert, "ssl_private_key", &pkey, "htdocs", &htd, @@ -205,7 +205,7 @@ int Web::parse(json_t *cfg) "enabled", &enabled ); if (ret) - throw ConfigError(cfg, err, "node-config-http"); + throw ConfigError(json, err, "node-config-http"); if (cert) ssl_cert = cert; @@ -246,7 +246,7 @@ void Web::start() #endif ctx_info.mounts = mounts; - logger->info("Starting sub-system: htdocs={}", htdocs.c_str()); + logger->info("Starting sub-system: htdocs={}", htdocs); /* update web root of mount point */ mounts[ARRAY_LEN(mounts)-1].origin = htdocs.c_str(); diff --git a/packaging/deps.sh b/packaging/deps.sh index 75ea0e914..9eefa5847 100644 --- a/packaging/deps.sh +++ b/packaging/deps.sh @@ -75,9 +75,9 @@ if ! pkg-config "fmt >= 6.1.2" && \ fi # Build & Install spdlog -if ! pkg-config "spdlog >= 1.5.0" && \ +if ! pkg-config "spdlog >= 1.8.2" && \ [ -z "${SKIP_SPDLOG}" ]; then - git clone --branch v1.5.0 --depth 1 --recursive https://github.com/gabime/spdlog.git + git clone --branch v1.8.2 --depth 1 --recursive https://github.com/gabime/spdlog.git mkdir -p spdlog/build pushd spdlog/build cmake -DSPDLOG_FMT_EXTERNAL=ON \ diff --git a/src/villas-hook.cpp b/src/villas-hook.cpp index 891716636..188888c16 100644 --- a/src/villas-hook.cpp +++ b/src/villas-hook.cpp @@ -72,12 +72,12 @@ public: if (ret) throw RuntimeError("Failed to initialize memory"); - cfg_cli = json_object(); + config_cli = json_object(); } ~Hook() { - json_decref(cfg_cli); + json_decref(config_cli); } protected: @@ -94,7 +94,7 @@ protected: int cnt; - json_t *cfg_cli; + json_t *config_cli; void handler(int signal, siginfo_t *sinfo, void *ctx) { @@ -162,7 +162,7 @@ protected: break; case 'o': - ret = json_object_extend_str(cfg_cli, optarg); + ret = json_object_extend_str(config_cli, optarg); if (ret) throw RuntimeError("Invalid option: {}", optarg); break; @@ -224,7 +224,7 @@ check: if (optarg == endptr) if (!h) throw RuntimeError("Failed to initialize hook"); - h->parse(cfg_cli); + h->parse(config_cli); h->check(); h->prepare(io.signals); h->start(); @@ -232,7 +232,7 @@ check: if (optarg == endptr) while (!stop) { ret = sample_alloc_many(&p, smps, cnt); if (ret != cnt) - throw RuntimeError("Failed to allocate %d smps from pool", cnt); + throw RuntimeError("Failed to allocate {} smps from pool", cnt); recv = io_scan(&io, smps, cnt); if (recv < 0) { diff --git a/src/villas-pipe.cpp b/src/villas-pipe.cpp index dd0995c84..4ed784335 100644 --- a/src/villas-pipe.cpp +++ b/src/villas-pipe.cpp @@ -62,18 +62,22 @@ protected: struct io *io; std::thread thread; + Logger logger; bool stop; bool enabled; int limit; public: - PipeDirection(struct vnode *n, struct io *i, bool en = true, int lim = -1) : + PipeDirection(struct vnode *n, struct io *i, bool en, int lim, const std::string &name) : node(n), io(i), stop(false), enabled(en), limit(lim) { + auto loggerName = fmt::format("pipe:{}", name); + logger = logging.get(loggerName); + /* Initialize memory */ unsigned vec = LOG2_CEIL(MAX(node->out.vectorize, node->in.vectorize)); unsigned pool_size = node_type(node)->pool_size ? node_type(node)->pool_size : vec; @@ -117,13 +121,11 @@ class PipeSendDirection : public PipeDirection { public: PipeSendDirection(struct vnode *n, struct io *i, bool en = true, int lim = -1) : - PipeDirection(n, i, en, lim) + PipeDirection(n, i, en, lim, "send") { } virtual void run() { - Logger logger = logging.get("pipe:send"); - unsigned last_sequenceno = 0, release; int scanned, sent, allocated, cnt = 0; @@ -189,13 +191,11 @@ class PipeReceiveDirection : public PipeDirection { public: PipeReceiveDirection(struct vnode *n, struct io *i, bool en = true, int lim = -1) : - PipeDirection(n, i, en, lim) + PipeDirection(n, i, en, lim, "recv") { } virtual void run() { - Logger logger = logging.get("pipe:recv"); - int recv, cnt = 0, allocated = 0; unsigned release; struct sample *smps[node->in.vectorize]; @@ -248,7 +248,7 @@ public: reverse(false), format("villas.human"), dtypes("64f"), - cfg_cli(json_object()), + config_cli(json_object()), enable_send(true), enable_recv(true), limit_send(-1), @@ -263,7 +263,7 @@ public: ~Pipe() { - json_decref(cfg_cli); + json_decref(config_cli); } protected: @@ -279,7 +279,7 @@ protected: std::string uri; std::string nodestr; - json_t *cfg_cli; + json_t *config_cli; bool enable_send; bool enable_recv; @@ -369,7 +369,7 @@ protected: goto check; case 'o': - ret = json_object_extend_str(cfg_cli, optarg); + ret = json_object_extend_str(config_cli, optarg); if (ret) throw RuntimeError("Invalid option: {}", optarg); break; @@ -458,7 +458,7 @@ check: if (optarg == endptr) ret = node_prepare(node); if (ret) - throw RuntimeError("Failed to start node {}: reason={}", node_name(node), ret); + throw RuntimeError("Failed to prepare node {}: reason={}", node_name(node), ret); ret = node_start(node); if (ret) diff --git a/src/villas-relay.cpp b/src/villas-relay.cpp index 86f2f6645..9f80fe1c8 100644 --- a/src/villas-relay.cpp +++ b/src/villas-relay.cpp @@ -28,7 +28,6 @@ #include -#include #include #include @@ -53,7 +52,8 @@ RelaySession::RelaySession(Relay *r, Identifier sid) : identifier(sid), connects(0) { - Logger logger = villas::logging.get("console"); + auto loggerName = fmt::format("relay:{}", sid); + logger = villas::logging.get(loggerName); logger->info("RelaySession created: {}", identifier); @@ -66,8 +66,6 @@ RelaySession::RelaySession(Relay *r, Identifier sid) : RelaySession::~RelaySession() { - Logger logger = villas::logging.get("console"); - logger->info("RelaySession destroyed: {}", identifier); sessions.erase(identifier); @@ -75,8 +73,6 @@ RelaySession::~RelaySession() RelaySession * RelaySession::get(Relay *r, lws *wsi) { - Logger logger = villas::logging.get("console"); - char uri[64]; /* We use the URI to associate this connection to a session @@ -100,6 +96,7 @@ RelaySession * RelaySession::get(Relay *r, lws *wsi) return rs; } else { + auto logger = logging.get("villas-relay"); logger->info("Found existing session: {}", sid); return it->second; @@ -140,8 +137,6 @@ RelayConnection::RelayConnection(Relay *r, lws *w, bool lo) : frames_sent(0), loopback(lo) { - Logger logger = villas::logging.get("console"); - session = RelaySession::get(r, wsi); session->connections[wsi] = this; session->connects++; @@ -150,14 +145,12 @@ RelayConnection::RelayConnection(Relay *r, lws *w, bool lo) : created = time(nullptr); - logger->info("New connection established: session={}, remote={} ({})", session->identifier, name, ip); + session->logger->info("New connection established: {} ({})", name, ip); } RelayConnection::~RelayConnection() { - Logger logger = villas::logging.get("console"); - - logger->info("RelayConnection closed: session={}, remote={} ({})", session->identifier, name, ip); + session->logger->info("RelayConnection closed: {} ({})", name, ip); session->connections.erase(wsi); @@ -199,15 +192,13 @@ void RelayConnection::write() void RelayConnection::read(void *in, size_t len) { - Logger logger = villas::logging.get("console"); - currentFrame->insert(currentFrame->end(), (uint8_t *) in, (uint8_t *) in + len); bytes_recv += len; if (lws_is_final_fragment(wsi)) { frames_recv++; - logger->debug("Received frame, relaying to {} connections", session->connections.size() - (loopback ? 0 : 1)); + session->logger->debug("Received frame, relaying to {} connections", session->connections.size() - (loopback ? 0 : 1)); for (auto p : session->connections) { auto c = p.second; @@ -252,7 +243,6 @@ Relay::Relay(int argc, char *argv[]) : throw RuntimeError("Failed to initialize memory"); /* Initialize logging */ - spdlog::stdout_color_mt("lws"); lws_set_log_level((1 << LLL_COUNT) - 1, loggerCallback); protocols = { @@ -280,7 +270,7 @@ Relay::Relay(int argc, char *argv[]) : void Relay::loggerCallback(int level, const char *msg) { - auto log = spdlog::get("lws"); + auto logger = logging.get("lws"); char *nl = (char *) strchr(msg, '\n'); if (nl) @@ -292,19 +282,19 @@ void Relay::loggerCallback(int level, const char *msg) switch (level) { case LLL_ERR: - log->error("{}", msg); + logger->error("{}", msg); break; case LLL_WARN: - log->warn( "{}", msg); + logger->warn( "{}", msg); break; case LLL_INFO: - log->info( "{}", msg); + logger->info( "{}", msg); break; default: - log->debug("{}", msg); + logger->debug("{}", msg); break; } } @@ -441,7 +431,7 @@ void Relay::parse() while ((c = getopt (argc, argv, "hVp:P:ld:u:")) != -1) { switch (c) { case 'd': - spdlog::set_level(spdlog::level::from_str(optarg)); + logging.setLevel(optarg); break; case 'p': @@ -503,15 +493,17 @@ int Relay::main() { ctx_info.mounts = &mount; ctx_info.user = (void *) this; + auto lwsLogger = logging.get("lws"); + context = lws_create_context(&ctx_info); if (context == nullptr) { - logger->error("WebSocket: failed to initialize server context"); + lwsLogger->error("Failed to initialize server context"); exit(EXIT_FAILURE); } vhost = lws_create_vhost(context, &ctx_info); if (vhost == nullptr) { - logger->error("WebSocket: failed to initialize virtual host"); + lwsLogger->error("Failed to initialize virtual host"); exit(EXIT_FAILURE); } diff --git a/src/villas-relay.hpp b/src/villas-relay.hpp index 1e38bf8e1..22a2850e3 100644 --- a/src/villas-relay.hpp +++ b/src/villas-relay.hpp @@ -24,11 +24,12 @@ #include #include -#include #include #include +#include + namespace villas { namespace node { namespace tools { @@ -68,6 +69,7 @@ protected: uuid_t uuid; Identifier identifier; + Logger logger; std::map connections; diff --git a/src/villas-signal.cpp b/src/villas-signal.cpp index 85f746670..7e0ee42f8 100644 --- a/src/villas-signal.cpp +++ b/src/villas-signal.cpp @@ -198,8 +198,6 @@ check: if (optarg == endptr) void handler(int signal, siginfo_t *sinfo, void *ctx) { - Logger logger = logging.get("signal"); - switch (signal) { case SIGALRM: logger->info("Reached timeout. Terminating..."); @@ -215,7 +213,7 @@ check: if (optarg == endptr) int main() { int ret; - json_t *cfg; + json_t *json; struct vnode_type *nt; struct format_type *ft; @@ -229,8 +227,8 @@ check: if (optarg == endptr) if (ret) throw RuntimeError("Failed to initialize node"); - cfg = parse_cli(argc, argv); - if (!cfg) { + json = parse_cli(argc, argv); + if (!json) { usage(); exit(EXIT_FAILURE); } @@ -238,7 +236,7 @@ check: if (optarg == endptr) uuid_t uuid; uuid_clear(uuid); - ret = node_parse(&n, cfg, uuid); + ret = node_parse(&n, json, uuid); if (ret) { usage(); exit(EXIT_FAILURE); @@ -259,7 +257,7 @@ check: if (optarg == endptr) ret = node_prepare(&n); if (ret) - throw RuntimeError("Failed to start node {}: reason={}", node_name(&n), ret); + throw RuntimeError("Failed to prepare node {}: reason={}", node_name(&n), ret); ret = io_init(&io, ft, &n.in.signals, (int) IOFlags::FLUSH | ((int) SampleFlags::HAS_ALL & ~(int) SampleFlags::HAS_OFFSET)); if (ret) diff --git a/src/villas-test-rtt.cpp b/src/villas-test-rtt.cpp index 9e4f241a6..b9b73b90c 100644 --- a/src/villas-test-rtt.cpp +++ b/src/villas-test-rtt.cpp @@ -194,7 +194,7 @@ check: if (optarg == endptr) ret = node_prepare(node); if (ret) - throw RuntimeError("Failed to start node {}: reason={}", node_name(node), ret); + throw RuntimeError("Failed to prepare node {}: reason={}", node_name(node), ret); ret = node_start(node); if (ret) @@ -241,7 +241,7 @@ check: if (optarg == endptr) else throw RuntimeError("Invalid file descriptor: {}", fd); - hist.print(true); + hist.print(logger, true); ret = node_stop(node); if (ret) diff --git a/tests/integration/api-config.sh b/tests/integration/api-config.sh index 11a0e0bc0..54cd54370 100755 --- a/tests/integration/api-config.sh +++ b/tests/integration/api-config.sh @@ -43,7 +43,7 @@ EOF ID=$(uuidgen) -# Start VILLASnode instance with local config (via advio) +# Start VILLASnode instance with local config villas-node ${CONFIG_FILE} & # Wait for node to complete init diff --git a/tests/integration/api-nodes.sh b/tests/integration/api-nodes.sh index 5ecf57746..be1cd159f 100755 --- a/tests/integration/api-nodes.sh +++ b/tests/integration/api-nodes.sh @@ -62,7 +62,7 @@ cat > ${CONFIG_FILE} < ${CONFIG_FILE} < -# @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC -# @license GNU General Public License (version 3) -# -# VILLASnode -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -################################################################################## - -SCRIPT=$(realpath $0) -SCRIPTPATH=$(dirname ${SCRIPT}) -source ${SCRIPTPATH}/../../tools/villas-helper.sh - -CONFIG_FILE=$(mktemp) -INPUT_FILE=$(mktemp) -OUTPUT_FILE=$(mktemp) - -NUM_SAMPLES=${NUM_SAMPLES:-10} - -URI=https://Q9ZHPBD5eRlZcAi:badpass@rwth-aachen.sciebo.de/public.php/webdav/tests/pipe - -# WebDav / OwnCloud / Sciebo do not support partial upload -# So we do not flush the output -cat > ${CONFIG_FILE} < /dev/null - -# Generate test data -VILLAS_LOG_PREFIX=$(colorize "[Signal] ") \ -villas-signal -n -l ${NUM_SAMPLES} random > ${INPUT_FILE} - -# Upload data to cloud -VILLAS_LOG_PREFIX=$(colorize "[Send] ") \ -villas-pipe -s ${CONFIG_FILE} remote_file < ${INPUT_FILE} - -# Download data from the cloud -VILLAS_LOG_PREFIX=$(colorize "[Recv] ") \ -villas-pipe -r -l ${NUM_SAMPLES} ${CONFIG_FILE} remote_file > ${OUTPUT_FILE} - -# Compare results -villas-test-cmp ${INPUT_FILE} ${OUTPUT_FILE} -RC=$? - -rm -f ${CONFIG_FILE} ${INPUT_FILE} ${OUTPUT_FILE} - -exit ${RC} diff --git a/tests/unit/io.cpp b/tests/unit/io.cpp index 0b3518c09..720dde49b 100644 --- a/tests/unit/io.cpp +++ b/tests/unit/io.cpp @@ -346,7 +346,6 @@ ParameterizedTest(Param *p, io, highlevel, .init = init_memory) retp = mkdtemp(dir); cr_assert_not_null(retp); -// ret = asprintf(&fn, "file://%s/file", dir); ret = asprintf(&fn, "%s/file", dir); cr_assert_gt(ret, 0); @@ -376,9 +375,6 @@ ParameterizedTest(Param *p, io, highlevel, .init = init_memory) io_rewind(&io); - if (io.mode == IOMode::ADVIO) - adownload(io.in.stream.adv, 0); - cnt = io_scan(&io, smpt, p->cnt); cr_assert_gt(cnt, 0, "Failed to read samples back: cnt=%d", cnt); diff --git a/tests/unit/queue.cpp b/tests/unit/queue.cpp index 2164890b1..95d02d50e 100644 --- a/tests/unit/queue.cpp +++ b/tests/unit/queue.cpp @@ -88,13 +88,9 @@ static void * producer(void *ctx) int ret; struct param *p = (struct param *) ctx; - Logger logger = logging.get("test:queue:producer"); - srand((unsigned) time(0) + thread_get_id()); size_t nops = rand() % 1000; - //logger->info("tid = {}", thread_get_id()); - #ifdef __APPLE__ #define pthread_yield pthread_yield_np #endif @@ -102,14 +98,10 @@ static void * producer(void *ctx) while (p->start == 0) pthread_yield(); - //logger->info("wait for {} nops", nops); - /* Wait for a random time */ for (size_t i = 0; i != nops; i += 1) nop(); - //logger->info("start pushing"); - /* Enqueue */ for (intptr_t count = 0; count < p->iter_count; count++) { do { @@ -118,8 +110,6 @@ static void * producer(void *ctx) } while (ret != 1); } - //logger->info("finished"); - return nullptr; } @@ -131,22 +121,14 @@ static void * consumer(void *ctx) srand((unsigned) time(0) + thread_get_id()); size_t nops = rand() % 1000; - Logger logger = logging.get("test:queue:consumer"); - - //logger->info("tid = {}", thread_get_id()); - /* Wait for global start signal */ while (p->start == 0) pthread_yield(); - //logger->info("wait for {} nops", nops); - /* Wait for a random time */ for (size_t i = 0; i != nops; i += 1) nop(); - //logger->info("start pulling"); - /* Dequeue */ for (intptr_t count = 0; count < p->iter_count; count++) { intptr_t ptr; @@ -160,8 +142,6 @@ static void * consumer(void *ctx) //cr_assert_eq((intptr_t) ptr, count); } - //logger->info("finished"); - return nullptr; } @@ -344,9 +324,9 @@ ParameterizedTest(struct param *p, queue, multi_threaded, .timeout = 20, .init = cycpop = (end_tsc_time - start_tsc_time) / p->iter_count; if (cycpop < 400) - logger->debug("cycles/op: {}", cycpop); + logger->debug("Cycles/op: {}", cycpop); else - logger->warn("cycles/op are very high ({}). Are you running on a hypervisor?", cycpop); + logger->warn("Cycles/op are very high ({}). Are you running on a hypervisor?", cycpop); ret = queue_available(&q); cr_assert_eq(ret, 0); diff --git a/tools/start_fpga.sh b/tools/start_fpga.sh new file mode 100755 index 000000000..813325381 --- /dev/null +++ b/tools/start_fpga.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +ARGS="$@" + +FPGA=root@137.226.133.220 + +BUILDDIR=${BUILDDIR:-$(pwd)} + +mkdir -p out +make install DESTDIR=${BUILDDIR}/out + +ssh-copy-id -i ~/.ssh/id_rsa ${FPGA} + +rsync --progress -a ${BUILDDIR}/out/usr/local/ ${FPGA}:/villas/ + +ssh ${FPGA} <<'ENDSSH' +# commands to run on remote host + +mkdir -p /etc/ld.so.conf.d/ +echo "/villas/lib" > /etc/ld.so.conf.d/villas.conf +ldconfig +villas-node -V +ENDSSH + +ssh ${FPGA} /villas/bin/villas-node