20#define native_http_access_log_strdup _strdup
23#define native_http_access_log_strdup strdup
34 return fclose(file) == 0 ? 0 : -1;
41 gettimeofday(&tv, NULL);
43 gmtime_s(&tm_utc, (
const time_t *)&tv.tv_sec);
45 gmtime_r(&tv.tv_sec, &tm_utc);
47 strftime(buffer,
sizeof(buffer),
"%Y%m%d.%H%M%S.", &tm_utc);
48 snprintf(buffer + strlen(buffer),
sizeof(buffer) - strlen(buffer),
"%03ld", (
long)(tv.tv_usec / 1000));
53 if (error_report_path != NULL && error_report_path[0] !=
'\0') {
57 size_t needed = strlen(
"/var/log/pharos/.error.jsonl") + strlen(app_id != NULL && app_id[0] !=
'\0' ? app_id :
"app") + 1;
58 char *resolved = (
char *)malloc(needed);
59 if (resolved != NULL) {
60 snprintf(resolved, needed,
"/var/log/pharos/%s.error.jsonl", app_id != NULL && app_id[0] !=
'\0' ? app_id :
"app");
66static void write_error_report_native(
const char *app_id,
const char *error_report_path,
const HttpRequest *request,
const char *request_path,
const char *status_text,
const char *reason,
const char *resource_path,
const char *detail_text) {
67 char *resolved_path = NULL;
68 char *timestamp = NULL;
70 char *app_id_json = NULL;
71 char *timestamp_json = NULL;
72 char *status_json = NULL;
73 char *reason_json = NULL;
74 char *method_json = NULL;
75 char *path_json = NULL;
76 char *client_ip_json = NULL;
77 char *resource_path_json = NULL;
78 char *detail_json = NULL;
81 if (request == NULL) {
85 if (resolved_path == NULL) {
93 const char *fallback_app = app_id != NULL && app_id[0] !=
'\0' ? app_id :
"app";
94 size_t needed = strlen(
"/tmp/pharos/.error.jsonl") + strlen(fallback_app) + 1;
95 resolved_path = (
char *)malloc(needed);
96 if (resolved_path == NULL) {
99 snprintf(resolved_path, needed,
"/tmp/pharos/%s.error.jsonl", fallback_app);
107 file = fopen(resolved_path,
"ab");
123 if (app_id_json != NULL && timestamp_json != NULL && status_json != NULL && reason_json != NULL && method_json != NULL && path_json != NULL && client_ip_json != NULL && resource_path_json != NULL && detail_json != NULL) {
124 if (fprintf(file,
"{\"timestamp\":%s,\"app_id\":%s,\"status\":%s,\"reason\":%s,\"method\":%s,\"path\":%s,\"client_ip\":%s,\"resource_path\":%s,\"detail\":%s}\n", timestamp_json, app_id_json, status_json, reason_json, method_json, path_json, client_ip_json, resource_path_json, detail_json) < 0) {
131 free(timestamp_json);
136 free(client_ip_json);
137 free(resource_path_json);
142void native_write_error_log(
const char *log_path,
const char *error_report_path,
const char *app_id,
const HttpRequest *request,
const char *request_path,
const char *status_text,
const char *reason,
const char *resource_path,
const char *detail_text) {
144 char *timestamp = NULL;
145 char *real_ip = NULL;
146 char *headers_with_ip = NULL;
147 char *headers_compact = NULL;
149 if (log_path == NULL || log_path[0] ==
'\0' || request == NULL) {
157 file = fopen(log_path,
"ab");
165 if (timestamp != NULL && real_ip != NULL && headers_compact != NULL) {
168 "%s error app=%s status: \"%s\" method: \"%s\" path: \"%s\" headers: \"%s\" reason: \"%s\"",
170 app_id != NULL && app_id[0] !=
'\0' ? app_id :
"app",
171 status_text != NULL ? status_text :
"500 Internal Server Error",
173 request_path != NULL ? request_path :
"",
175 reason != NULL ? reason :
"http_response"
177 if (resource_path != NULL && resource_path[0] !=
'\0') {
178 fprintf(file,
" resource: \"%s\"", resource_path);
180 if (detail_text != NULL && detail_text[0] !=
'\0') {
182 if (detail_compact != NULL) {
183 fprintf(file,
" detail: \"%s\"", detail_compact);
185 free(detail_compact);
191 free(headers_with_ip);
192 free(headers_compact);
194 write_error_report_native(app_id, error_report_path, request, request_path, status_text, reason, resource_path, detail_text);
199 char *timestamp = NULL;
200 char *real_ip = NULL;
201 char *headers_with_ip = NULL;
202 char *headers_compact = NULL;
204 if (log_path == NULL || log_path[0] ==
'\0' || request == NULL) {
212 file = fopen(log_path,
"ab");
220 if (timestamp != NULL && real_ip != NULL && headers_compact != NULL) {
223 "%s access status: \"%s\" method: \"%s\" path: \"%s\" headers: \"%s\"\n",
227 request_path != NULL ? request_path :
"",
233 free(headers_with_ip);
234 free(headers_compact);
char * json_string_dup_native(const char *value)
Duplicates a string while escaping it for JSON string output.
Declares helpers that build native artifact and report payload strings.
int ensure_directory(const char *path)
Creates a directory path and any missing parent directories.
Declares native filesystem helper routines.
static void write_error_report_native(const char *app_id, const char *error_report_path, const HttpRequest *request, const char *request_path, const char *status_text, const char *reason, const char *resource_path, const char *detail_text)
static char * access_timestamp_native(void)
static char * resolved_error_report_path_native(const char *app_id, const char *error_report_path)
void native_write_access_log(const char *log_path, const HttpRequest *request, const char *request_path, int status_code)
Writes one access log entry for a completed HTTP request.
#define native_http_access_log_strdup
static int close_logged_file_native(FILE *file)
void native_write_error_log(const char *log_path, const char *error_report_path, const char *app_id, const HttpRequest *request, const char *request_path, const char *status_text, const char *reason, const char *resource_path, const char *detail_text)
Writes one structured error log entry and its paired JSONL error report.
Declares native access log and error log helpers.
char * compact_log_text_native(const char *value)
Compacts free-form text into a single-line log-safe representation.
char * request_real_ip_native(const char *headers)
Extracts the best client IP address from request headers.
char * request_headers_with_client_ip_native(const char *headers, const char *client_ip)
Returns request headers with an explicit client IP header applied.
const char * http_status_text_native(int status_code)
Returns the canonical reason phrase for one HTTP status code.
Declares HTTP logging and response formatting helpers.
char * path_dirname(const char *path)
Returns the parent directory component of a path.
Declares shared low-level support helpers used across the Pharos native runtime.
Parsed HTTP request fields extracted from a native connection.