Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions plugins/in_tail/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ endif()
if(MSVC)
set(src
${src}
win32/path.c
win32/stat.c
win32/io.c
)
Expand Down
9 changes: 9 additions & 0 deletions plugins/in_tail/tail.c
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,15 @@ static struct flb_config_map config_map[] = {
"set to false to use file stat watcher instead of inotify."
},
#endif
#ifdef FLB_SYSTEM_WINDOWS
{
FLB_CONFIG_MAP_STR, "windows.path_encoding", "ansi",
0, FLB_FALSE, 0,
"Windows-only path encoding mode. Use 'utf-8' to treat paths as UTF-8 "
"and call Windows wide-character file APIs. The default 'ansi' mode "
"keeps the legacy active ANSI code page behavior."
},
#endif
#ifdef FLB_HAVE_REGEX
{
FLB_CONFIG_MAP_STR, "parser", NULL,
Expand Down
21 changes: 21 additions & 0 deletions plugins/in_tail/tail_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ struct flb_tail_config *flb_tail_config_create(struct flb_input_instance *ins,
#ifdef FLB_HAVE_SQLDB
ctx->db_sync = 1; /* sqlite sync 'normal' */
#endif
#ifdef FLB_SYSTEM_WINDOWS
ctx->windows_path_encoding = FLB_TAIL_WINDOWS_PATH_ENCODING_ANSI;
#endif
#ifdef FLB_HAVE_UNICODE_ENCODER
ctx->preferred_input_encoding = FLB_UNICODE_ENCODING_UNSPECIFIED;
#endif
Expand Down Expand Up @@ -196,6 +199,24 @@ struct flb_tail_config *flb_tail_config_create(struct flb_input_instance *ins,
return NULL;
}

#ifdef FLB_SYSTEM_WINDOWS
tmp = flb_input_get_property("windows.path_encoding", ins);
if (tmp) {
if (strcasecmp(tmp, "ansi") == 0) {
ctx->windows_path_encoding = FLB_TAIL_WINDOWS_PATH_ENCODING_ANSI;
}
else if (strcasecmp(tmp, "utf-8") == 0 ||
strcasecmp(tmp, "utf8") == 0) {
ctx->windows_path_encoding = FLB_TAIL_WINDOWS_PATH_ENCODING_UTF8;
}
else {
flb_plg_error(ctx->ins, "invalid 'windows.path_encoding' value %s", tmp);
flb_tail_config_destroy(ctx);
return NULL;
}
}
#endif

#ifdef FLB_HAVE_UNICODE_ENCODER
tmp = flb_input_get_property("unicode.encoding", ins);
if (tmp) {
Expand Down
8 changes: 8 additions & 0 deletions plugins/in_tail/tail_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@
#define FLB_TAIL_METRIC_L_SKIPPED 105 /* number of skipped occurrences of long lines */
#endif

#ifdef FLB_SYSTEM_WINDOWS
#define FLB_TAIL_WINDOWS_PATH_ENCODING_ANSI 0
#define FLB_TAIL_WINDOWS_PATH_ENCODING_UTF8 1
#endif

struct flb_tail_config {
int fd_notify; /* inotify fd */
flb_pipefd_t ch_manager[2]; /* pipe: channel manager */
Expand Down Expand Up @@ -96,6 +101,9 @@ struct flb_tail_config {
* being ingested */
time_t last_pending; /* last time a 'pending signal' was emitted' */
struct mk_list *path_list; /* list of paths to scan (glob) */
#ifdef FLB_SYSTEM_WINDOWS
int windows_path_encoding; /* Windows path API encoding mode */
#endif
flb_sds_t path_key; /* key name of file path */
flb_sds_t key; /* key for unstructured record */
int skip_long_lines; /* skip long lines */
Expand Down
106 changes: 96 additions & 10 deletions plugins/in_tail/tail_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,62 @@

#define FLB_TAIL_DB_OFFSET_MARKER_SIZE 32

#ifdef FLB_SYSTEM_WINDOWS
static inline int tail_file_open(struct flb_tail_config *ctx, const char *path,
int flags)
{
if (ctx->windows_path_encoding == FLB_TAIL_WINDOWS_PATH_ENCODING_UTF8) {
return win32_open_utf8(path, flags);
}

return open(path, flags);
}

static inline int tail_file_stat(struct flb_tail_config *ctx, const char *path,
struct stat *st)
{
if (ctx->windows_path_encoding == FLB_TAIL_WINDOWS_PATH_ENCODING_UTF8) {
return win32_stat_utf8(path, st);
}

return stat(path, st);
}

static inline int tail_file_lstat(struct flb_tail_config *ctx, const char *path,
struct stat *st)
{
if (ctx->windows_path_encoding == FLB_TAIL_WINDOWS_PATH_ENCODING_UTF8) {
return win32_lstat_utf8(path, st);
}

return lstat(path, st);
}
#else
static inline int tail_file_open(struct flb_tail_config *ctx, const char *path,
int flags)
{
(void) ctx;

return open(path, flags);
}

static inline int tail_file_stat(struct flb_tail_config *ctx, const char *path,
struct stat *st)
{
(void) ctx;

return stat(path, st);
}

static inline int tail_file_lstat(struct flb_tail_config *ctx, const char *path,
struct stat *st)
{
(void) ctx;

return lstat(path, st);
}
#endif

static inline void consume_bytes(char *buf, int bytes, int length)
{
memmove(buf, buf + bytes, length - bytes);
Expand Down Expand Up @@ -1358,7 +1414,7 @@ int flb_tail_file_append(char *path, struct stat *st, int mode,
}
#endif

fd = open(path, O_RDONLY);
fd = tail_file_open(ctx, path, O_RDONLY);
if (fd == -1) {
flb_errno();
flb_plg_error(ctx->ins, "cannot open %s", path);
Expand All @@ -1378,7 +1434,7 @@ int flb_tail_file_append(char *path, struct stat *st, int mode,
file->tail_mode = mode;

/* On non-windows environments check if the original path is a link */
ret = lstat(path, &lst);
ret = tail_file_lstat(ctx, path, &lst);
if (ret == 0) {
if (S_ISLNK(lst.st_mode)) {
file->is_link = FLB_TRUE;
Expand Down Expand Up @@ -2113,7 +2169,7 @@ int flb_tail_file_is_rotated(struct flb_tail_config *ctx,

/* Check if the 'original monitored file' is a link and rotated */
if (file->is_link == FLB_TRUE) {
ret = lstat(file->name, &st);
ret = tail_file_lstat(ctx, file->name, &st);
if (ret == -1) {
/* Broken link or missing file */
if (errno == ENOENT) {
Expand Down Expand Up @@ -2148,7 +2204,7 @@ int flb_tail_file_is_rotated(struct flb_tail_config *ctx,


/* Get stats from the file name */
ret = stat(name, &st);
ret = tail_file_stat(ctx, name, &st);
if (ret == -1) {
flb_errno();
flb_free(name);
Expand Down Expand Up @@ -2283,6 +2339,7 @@ char *flb_tail_file_name(struct flb_tail_file *file)

#elif defined(FLB_SYSTEM_WINDOWS)
int len;
wchar_t *wide_buf;

h = (HANDLE) _get_osfhandle(file->fd);
if (h == INVALID_HANDLE_VALUE) {
Expand All @@ -2294,14 +2351,43 @@ char *flb_tail_file_name(struct flb_tail_file *file)
/* This function returns the length of the string excluding "\0"
* and the resulting path has a "\\?\" prefix.
*/
len = GetFinalPathNameByHandleA(h, buf, PATH_MAX, FILE_NAME_NORMALIZED);
if (len == 0 || len >= PATH_MAX) {
if (file->config->windows_path_encoding == FLB_TAIL_WINDOWS_PATH_ENCODING_UTF8) {
wide_buf = flb_calloc(PATH_MAX, sizeof(wchar_t));
if (wide_buf == NULL) {
flb_free(buf);
return NULL;
}

len = GetFinalPathNameByHandleW(h, wide_buf, PATH_MAX,
FILE_NAME_NORMALIZED);
if (len == 0 || len >= PATH_MAX) {
flb_free(wide_buf);
flb_free(buf);
return NULL;
}

if (wcsstr(wide_buf, L"\\\\?\\")) {
memmove(wide_buf, wide_buf + 4, (len + 1) * sizeof(wchar_t));
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

flb_free(buf);
return NULL;
buf = win32_wide_to_utf8(wide_buf);
flb_free(wide_buf);

if (buf == NULL) {
return NULL;
}
}
else {
len = GetFinalPathNameByHandleA(h, buf, PATH_MAX, FILE_NAME_NORMALIZED);
if (len == 0 || len >= PATH_MAX) {
flb_free(buf);
return NULL;
}

if (strstr(buf, "\\\\?\\")) {
memmove(buf, buf + 4, len + 1);
if (strstr(buf, "\\\\?\\")) {
memmove(buf, buf + 4, len + 1);
}
}
#elif defined(FLB_SYSTEM_FREEBSD)
if ((file_entries = kinfo_getfile(getpid(), &file_count)) == NULL) {
Expand Down Expand Up @@ -2396,7 +2482,7 @@ int flb_tail_file_rotated(struct flb_tail_file *file)
#endif

/* Check if a new file has been created */
ret = stat(tmp, &st);
ret = tail_file_stat(ctx, tmp, &st);
if (ret == 0 && st.st_ino != file->inode) {
if (flb_tail_file_exists(&st, ctx) == FLB_FALSE) {
ret = flb_tail_file_append(tmp, &st, FLB_TAIL_STATIC, -1, ctx);
Expand Down
14 changes: 13 additions & 1 deletion plugins/in_tail/tail_fs_stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@
#include "win32.h"
#endif

static int tail_fs_stat_path(struct flb_tail_config *ctx, const char *path,
struct stat *st)
{
#ifdef FLB_SYSTEM_WINDOWS
if (ctx->windows_path_encoding == FLB_TAIL_WINDOWS_PATH_ENCODING_UTF8) {
return win32_stat_utf8(path, st);
}
#endif

return stat(path, st);
}

struct fs_stat {
/* last time check */
time_t checked;
Expand Down Expand Up @@ -233,7 +245,7 @@ int flb_tail_fs_stat_add(struct flb_tail_file *file)
}

fst->checked = time(NULL);
ret = stat(file->name, &fst->st);
ret = tail_fs_stat_path(file->config, file->name, &fst->st);
if (ret == -1) {
flb_errno();
flb_free(fst);
Expand Down
Loading
Loading