diff --git a/scripts/base/frameworks/supervisor/api.zeek b/scripts/base/frameworks/supervisor/api.zeek index d335a04543..09a80d6cb5 100644 --- a/scripts/base/frameworks/supervisor/api.zeek +++ b/scripts/base/frameworks/supervisor/api.zeek @@ -23,6 +23,8 @@ export { name: string; interface: string &optional; directory: string &optional; + stdout_file: string &optional; + stderr_file: string &optional; scripts: vector of string &default = vector(); cpu_affinity: int &optional; cluster: table[string] of ClusterEndpoint &default=table(); diff --git a/src/Supervisor.cc b/src/Supervisor.cc index 1aef520686..ff26ca1f28 100644 --- a/src/Supervisor.cc +++ b/src/Supervisor.cc @@ -732,6 +732,16 @@ Supervisor::Node Supervisor::Node::FromRecord(const RecordVal* node) if ( directory_val ) rval.directory = directory_val->AsString()->CheckString(); + auto stdout_val = node->Lookup("stdout_file"); + + if ( stdout_val ) + rval.stdout_file = stdout_val->AsString()->CheckString(); + + auto stderr_val = node->Lookup("stderr_file"); + + if ( stderr_val ) + rval.stderr_file = stderr_val->AsString()->CheckString(); + auto affinity_val = node->Lookup("cpu_affinity"); if ( affinity_val ) @@ -786,6 +796,12 @@ Supervisor::Node Supervisor::Node::FromJSON(std::string_view json) if ( auto it = j.find("directory"); it != j.end() ) rval.directory = *it; + if ( auto it = j.find("stdout_file"); it != j.end() ) + rval.stdout_file= *it; + + if ( auto it = j.find("stderr_file"); it != j.end() ) + rval.stderr_file= *it; + if ( auto it = j.find("cpu_affinity"); it != j.end() ) rval.cpu_affinity = *it; @@ -841,6 +857,12 @@ IntrusivePtr Supervisor::Node::ToRecord() const if ( directory ) rval->Assign(rt->FieldOffset("directory"), new StringVal(*directory)); + if ( stdout_file ) + rval->Assign(rt->FieldOffset("stdout_file"), new StringVal(*stdout_file)); + + if ( stderr_file ) + rval->Assign(rt->FieldOffset("stderr_file"), new StringVal(*stderr_file)); + if ( cpu_affinity ) rval->Assign(rt->FieldOffset("cpu_affinity"), val_mgr->GetInt(*cpu_affinity)); diff --git a/src/Supervisor.h b/src/Supervisor.h index 623afc36a0..1eeab43998 100644 --- a/src/Supervisor.h +++ b/src/Supervisor.h @@ -47,6 +47,8 @@ public: std::string name; std::optional interface; std::optional directory; + std::optional stdout_file; + std::optional stderr_file; std::optional cpu_affinity; std::vector scripts; std::map cluster; diff --git a/src/main.cc b/src/main.cc index 021c5207aa..81c138ee11 100644 --- a/src/main.cc +++ b/src/main.cc @@ -936,22 +936,8 @@ int main(int argc, char** argv) { // TODO: probably all of this block could move to a new // zeek::supervised_node->Init(options) method - options.filter_supervised_node_options(zeek::supervised_node); const auto& node_name = zeek::supervised_node->name; - if ( zeek::supervised_node->interface ) - options.interfaces.emplace_back(*zeek::supervised_node->interface); - - if ( ! zeek::supervised_node->cluster.empty() ) - { - if ( setenv("CLUSTER_NODE", node_name.data(), true) == -1 ) - { - fprintf(stderr, "node '%s' failed to setenv: %s\n", - node_name.data(), strerror(errno)); - exit(1); - } - } - if ( zeek::supervised_node->directory ) { if ( chdir(zeek::supervised_node->directory->data()) ) @@ -964,6 +950,38 @@ int main(int argc, char** argv) } } + if ( zeek::supervised_node->stderr_file ) + { + auto fd = open(zeek::supervised_node->stderr_file->data(), + O_WRONLY | O_CREAT | O_TRUNC | O_APPEND | O_CLOEXEC, + 0600); + + if ( fd == -1 || dup2(fd, STDERR_FILENO) == -1 ) + { + fprintf(stderr, "node '%s' failed to create stderr file %s: %s\n", + node_name.data(), + zeek::supervised_node->stderr_file->data(), + strerror(errno)); + exit(1); + } + } + + if ( zeek::supervised_node->stdout_file ) + { + auto fd = open(zeek::supervised_node->stdout_file->data(), + O_WRONLY | O_CREAT | O_TRUNC | O_APPEND | O_CLOEXEC, + 0600); + + if ( fd == -1 || dup2(fd, STDOUT_FILENO) == -1 ) + { + fprintf(stderr, "node '%s' failed to create stdout file %s: %s\n", + node_name.data(), + zeek::supervised_node->stdout_file->data(), + strerror(errno)); + exit(1); + } + } + if ( zeek::supervised_node->cpu_affinity ) { auto res = zeek::set_affinity(*zeek::supervised_node->cpu_affinity); @@ -973,6 +991,21 @@ int main(int argc, char** argv) node_name.data(), strerror(errno)); } + options.filter_supervised_node_options(zeek::supervised_node); + + if ( zeek::supervised_node->interface ) + options.interfaces.emplace_back(*zeek::supervised_node->interface); + + if ( ! zeek::supervised_node->cluster.empty() ) + { + if ( setenv("CLUSTER_NODE", node_name.data(), true) == -1 ) + { + fprintf(stderr, "node '%s' failed to setenv: %s\n", + node_name.data(), strerror(errno)); + exit(1); + } + } + for ( const auto& s : zeek::supervised_node->scripts ) options.scripts_to_load.emplace_back(s); }