Skip to content
Open
Show file tree
Hide file tree
Changes from all 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 (wcsncmp(wide_buf, L"\\\\?\\", 4) == 0) {
memmove(wide_buf, wide_buf + 4, (len - 3) * sizeof(wchar_t));
}

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