diff --git a/.github/workflows/MainDistributionPipeline.yml b/.github/workflows/MainDistributionPipeline.yml index bfb8cb4..77f7de4 100644 --- a/.github/workflows/MainDistributionPipeline.yml +++ b/.github/workflows/MainDistributionPipeline.yml @@ -4,6 +4,9 @@ name: Main Extension Distribution Pipeline on: push: + paths-ignore: + - '**.md' + - '**..yml' pull_request: workflow_dispatch: diff --git a/docs/README.md b/docs/README.md index 7211800..532468b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -41,6 +41,7 @@ LOAD httpserver; Start the HTTP server providing the `host`, `port` and `auth` parameters.
> * If you want no authentication, just pass an empty string as parameter.
> * If you want the API run in foreground set `DUCKDB_HTTPSERVER_FOREGROUND=1` +> * If you want logs set `DUCKDB_HTTPSERVER_DEBUG` or `DUCKDB_HTTPSERVER_SYSLOG` #### Basic Auth ```sql @@ -90,7 +91,7 @@ D SELECT * FROM duck_flock('SELECT version()', ['http://localhost:9999']); │ "version"() │ │ varchar │ ├─────────────┤ -│ v1.1.1 │ +│ v1.1.3 │ └─────────────┘ ``` @@ -122,7 +123,7 @@ curl -X POST -d "SELECT 'hello', version()" "http://localhost:9999/?default_form "data": [ [ "hello", - "v1.1.1" + "v1.1.3" ] ], "rows": 1, @@ -153,7 +154,7 @@ D SELECT * FROM read_json_auto('http://localhost:9999/?q=SELECT version()'); │ "version"() │ │ varchar │ ├─────────────┤ -│ v1.1.1 │ +│ v1.1.3 │ └─────────────┘ ``` diff --git a/duckdb b/duckdb index af39bd0..1986445 160000 --- a/duckdb +++ b/duckdb @@ -1 +1 @@ -Subproject commit af39bd0dcf66876e09ac2a7c3baa28fe1b301151 +Subproject commit 19864453f7d0ed095256d848b46e7b8630989bac diff --git a/src/httpserver_extension.cpp b/src/httpserver_extension.cpp index 88078f7..12ee33a 100644 --- a/src/httpserver_extension.cpp +++ b/src/httpserver_extension.cpp @@ -9,16 +9,18 @@ #include "duckdb/common/exception/http_exception.hpp" #include "duckdb/common/allocator.hpp" #include +#include +#include +#include + +#ifndef _WIN32 +#include +#endif #define CPPHTTPLIB_OPENSSL_SUPPORT #include "httplib.hpp" - -// Include yyjson for JSON handling #include "yyjson.hpp" -#include -#include -#include #include "play.h" using namespace duckdb_yyjson; // NOLINT @@ -384,6 +386,42 @@ void HttpServerStart(DatabaseInstance& db, string_t host, int32_t port, string_t string host_str = host.GetString(); + +#ifndef _WIN32 + const char* debug_env = std::getenv("DUCKDB_HTTPSERVER_DEBUG"); + const char* use_syslog = std::getenv("DUCKDB_HTTPSERVER_SYSLOG"); + + if (debug_env != nullptr && std::string(debug_env) == "1") { + global_state.server->set_logger([](const duckdb_httplib_openssl::Request& req, const duckdb_httplib_openssl::Response& res) { + time_t now_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + char timestr[32]; + strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&now_time)); + // Use \r\n for consistent line endings + fprintf(stdout, "[%s] %s %s - %d - from %s:%d\r\n", + timestr, + req.method.c_str(), + req.path.c_str(), + res.status, + req.remote_addr.c_str(), + req.remote_port); + fflush(stdout); + }); + } else if (use_syslog != nullptr && std::string(use_syslog) == "1") { + openlog("duckdb-httpserver", LOG_PID | LOG_NDELAY, LOG_LOCAL0); + global_state.server->set_logger([](const duckdb_httplib_openssl::Request& req, const duckdb_httplib_openssl::Response& res) { + syslog(LOG_INFO, "%s %s - %d - from %s:%d", + req.method.c_str(), + req.path.c_str(), + res.status, + req.remote_addr.c_str(), + req.remote_port); + }); + std::atexit([]() { + closelog(); + }); + } +#endif + const char* run_in_same_thread_env = std::getenv("DUCKDB_HTTPSERVER_FOREGROUND"); bool run_in_same_thread = (run_in_same_thread_env != nullptr && std::string(run_in_same_thread_env) == "1");