C# 期刊阅读器

问题描述 投票:0回答:1

在网上搜索解决方案但没有找到库后,我尝试使用 csharp 编写一个 systemd 日志阅读器,但运气不佳。

以下链接底部有一个用 C++ 编写的示例:

https://www.freedesktop.org/software/systemd/man/latest/sd_journal_next.html

<<< SEE UPDATE BELOW >>>

这是我到目前为止的代码,当我运行它时,我得到了

$ ./LogPublisher 
errno: 0
errno: -10
errno: -10
errno: -10 Message: 

据我所知,

-10
指的是
No child processes
,取自https://en.wikipedia.org/wiki/Errno.h

using System.Runtime.InteropServices;
using System.Text;

class Program
{
    enum Flags
    {
        SD_JOURNAL_LOCAL_ONLY = 1 << 0,                 // 0000 0001 = 1
        SD_JOURNAL_RUNTIME_ONLY = 1 << 1,               // 0000 0010 = 2
        SD_JOURNAL_SYSTEM = 1 << 2,                     // 0000 0100 = 4
        SD_JOURNAL_CURRENT_USER = 1 << 3,               // 0000 1000 = 8
        SD_JOURNAL_OS_ROOT = 1 << 4,                    // 0001 0000 = 16
        SD_JOURNAL_ALL_NAMESPACES = 1 << 5,             // (32) Show all namespaces, not just the default or specified one */
        SD_JOURNAL_INCLUDE_DEFAULT_NAMESPACE = 1 << 6,  // (64) Show default namespace in addition to specified one */
        SD_JOURNAL_TAKE_DIRECTORY_FD = 1 << 7,          // (128) sd_journal_open_directory_fd() will take ownership of the provided file descriptor. */
        SD_JOURNAL_ASSUME_IMMUTABLE = 1 << 8,           // (256) Assume the opened journal files are immutable. Journal entries added later may be ignored. */
    }


    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Journal
    {
        public int toplevel_fd;  // int toplevel_fd;
        public string path;  // char *path;
        public string prefix;  // char *prefix;
        public string _namespace;  // char *namespace;
        public UIntPtr files;  // OrderedHashmap *files;
        public UIntPtr files_cache;  // IteratedCache *files_cache;
        public UIntPtr mmap;  // MMapCache *mmap;
        public UIntPtr newest_by_boot_id;  // NewestByBootId *newest_by_boot_id;
        public ulong n_newest_by_boot_id;  // size_t n_newest_by_boot_id;
        public UIntPtr current_location;  // Location current_location;
        public UIntPtr current_file;  // JournalFile *current_file;
        public ulong current_field;  // uint64_t current_field;
        public UIntPtr level0;  // Match *level0;
        public UIntPtr level1;  // Match *level1;
        public UIntPtr level2;  // Match *level2;
        public UIntPtr exclude_syslog_identifiers;  // Set *exclude_syslog_identifiers;
        public ulong origin_id;  // uint64_t origin_id;
        public int inotify_fd;  // int inotify_fd;
        public uint current_invalidate_counter;  // unsigned current_invalidate_counter
        public uint last_invalidate_counter;  // unsigned last_invalidate_counter
        public ulong last_process_usec;  // usec_t last_process_usec;
        public uint generation;  // unsigned generation;
        public string unique_field;  // char *unique_field;
        public UIntPtr unique_file;  // JournalFile *unique_file;
        public ulong unique_offset;  // uint64_t unique_offset;
        public UIntPtr fields_file;  // JournalFile *fields_file;
        public ulong fields_offset;  // uint64_t fields_offset;
        public ulong fields_hash_table_index;  // uint64_t fields_hash_table_index;
        public string fields_buffer;  // char *fields_buffer;
        public int flags;  // int flags;
        public bool on_network = true;  // bool on_network:1;
        public bool no_new_files = true;  // bool no_new_files:1;
        public bool no_inotify = true;  // bool no_inotify:1;
        public bool unique_file_lost = true;  // bool unique_file_lost:1;
        public bool fields_file_lost = true;  // bool fields_file_lost:1;
        public bool has_runtime_files = true;  // bool has_runtime_files:1;
        public bool has_persistent_files = true;  // bool has_persistent_files:1;
        public ulong data_threshold;  // size_t data_threshold;
        public UIntPtr directories_by_path;  // Hashmap *directories_by_path;
        public UIntPtr directories_by_wd;  // Hashmap *directories_by_wd;
        public UIntPtr errors;  // Hashmap *errors;

        public Journal() { }
    }

    internal static class Systemd
    {
        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_open(ref Journal sd_journal, int flags);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern void sd_journal_close(ref Journal sd_journal);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_seek_head(ref Journal sd_journal);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_seek_tail(ref Journal sd_journal);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_next(ref Journal sd_journal);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_previous(ref Journal sd_journal);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_get_data(ref Journal sd_journal, string field, [Out] StringBuilder data, [Out] ulong length);
    }

    static void Main()
    {
        int errno;
        Journal j = new();

        errno = Systemd.sd_journal_open(ref j, (int)Flags.SD_JOURNAL_LOCAL_ONLY);
        Console.WriteLine($"errno: {errno}");

        Console.WriteLine($"path: {j.path}");

        errno = Systemd.sd_journal_seek_head(ref j);
        Console.WriteLine($"errno: {errno}");

        errno = Systemd.sd_journal_next(ref j);
        Console.WriteLine($"errno: {errno}");

        ulong length = 0;
        StringBuilder data = new(1024 * 768 * 4);

        errno = Systemd.sd_journal_get_data(ref j, "MESSAGE", data, length);
        Console.WriteLine($"errno: {errno} Message: {data}");

        Systemd.sd_journal_close(ref j);
    }
}

我一直在尝试参考日志的源代码来复制,但就是无法解决。

https://github.com/systemd/systemd/blob/main/src/systemd/sd-journal.h

参考上面的代码,为什么我会收到该错误? 我的代码是否走在正确的轨道上,还是偏离了正轨?我是否使用

ref Journal j
正确引用了《华尔街日报》?有没有人写过类似的东西并可以分享他们的代码?

更新

在评论中的感谢下,已经取得了进展。 现在的输出给了我

$ ./LogPublisher 
result: 0
result: 0
result: 1
result: -22 Message: 0 Length: 0

使用以下代码

using System.Runtime.InteropServices;
using System.Text;

class Program
{
    enum Flags
    {
        SD_JOURNAL_LOCAL_ONLY = 1 << 0,                 // 0000 0001 = 1
        SD_JOURNAL_RUNTIME_ONLY = 1 << 1,               // 0000 0010 = 2
        SD_JOURNAL_SYSTEM = 1 << 2,                     // 0000 0100 = 4
        SD_JOURNAL_CURRENT_USER = 1 << 3,               // 0000 1000 = 8
        SD_JOURNAL_OS_ROOT = 1 << 4,                    // 0001 0000 = 16
        SD_JOURNAL_ALL_NAMESPACES = 1 << 5,             // (32) Show all namespaces, not just the default or specified one */
        SD_JOURNAL_INCLUDE_DEFAULT_NAMESPACE = 1 << 6,  // (64) Show default namespace in addition to specified one */
        SD_JOURNAL_TAKE_DIRECTORY_FD = 1 << 7,          // (128) sd_journal_open_directory_fd() will take ownership of the provided file descriptor. */
        SD_JOURNAL_ASSUME_IMMUTABLE = 1 << 8,           // (256) Assume the opened journal files are immutable. Journal entries added later may be ignored. */
    }

    static class Systemd
    {
        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_open(ref UIntPtr sd_journal, int flags);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern void sd_journal_close(UIntPtr sd_journal);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_seek_head(UIntPtr sd_journal);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_seek_tail(UIntPtr sd_journal);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_step_one(UIntPtr sd_journal, int advanced);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_next(UIntPtr sd_journal);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_previous(UIntPtr sd_journal);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_get_data(UIntPtr sd_journal, string field, UIntPtr data, out ulong length);
    }

    static void Main()
    {
        int result; // negative number on error
        UIntPtr j = new();

        result = Systemd.sd_journal_open(ref j, (int)Flags.SD_JOURNAL_LOCAL_ONLY);
        Console.WriteLine($"result: {result}");  // return 0 on success

        result = Systemd.sd_journal_seek_head(j);
        Console.WriteLine($"result: {result}");  // return 0 on success

        result = Systemd.sd_journal_step_one(j, 0);
        Console.WriteLine($"result: {result}");  // return the number of entries advanced/set back on success

        UIntPtr data = new();

        result = Systemd.sd_journal_get_data(j, "MESSAGE", data, out ulong length);
        Console.WriteLine($"result: {result} Message: {data} Length: {length}");

        Systemd.sd_journal_close(j);
    }
}

还没有完全实现,因为我没有从 get_data 得到结果...

c# systemd systemd-journald
1个回答
0
投票
using System.Runtime.InteropServices;

class Program
{
    enum Flags
    {
        SD_JOURNAL_LOCAL_ONLY = 1 << 0,                 // 0000 0001 = 1
        SD_JOURNAL_RUNTIME_ONLY = 1 << 1,               // 0000 0010 = 2
        SD_JOURNAL_SYSTEM = 1 << 2,                     // 0000 0100 = 4
        SD_JOURNAL_CURRENT_USER = 1 << 3,               // 0000 1000 = 8
        SD_JOURNAL_OS_ROOT = 1 << 4,                    // 0001 0000 = 16
        SD_JOURNAL_ALL_NAMESPACES = 1 << 5,             // (32) Show all namespaces, not just the default or specified one */
        SD_JOURNAL_INCLUDE_DEFAULT_NAMESPACE = 1 << 6,  // (64) Show default namespace in addition to specified one */
        SD_JOURNAL_TAKE_DIRECTORY_FD = 1 << 7,          // (128) sd_journal_open_directory_fd() will take ownership of the provided file descriptor. */
        SD_JOURNAL_ASSUME_IMMUTABLE = 1 << 8,           // (256) Assume the opened journal files are immutable. Journal entries added later may be ignored. */
    }

    static class Systemd
    {
        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_open(ref UIntPtr sd_journal, int flags);
        // int sd_journal_open(sd_journal **ret, int flags);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern void sd_journal_close(UIntPtr sd_journal);
        // void sd_journal_close(sd_journal *j);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_seek_head(UIntPtr sd_journal);
        // int sd_journal_seek_head(sd_journal *j);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_seek_tail(UIntPtr sd_journal);
        // int sd_journal_seek_tail(sd_journal *j);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_step_one(UIntPtr sd_journal, int advanced);
        // int sd_journal_step_one(sd_journal *j, int advanced);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_next(UIntPtr sd_journal);
        // int sd_journal_next(sd_journal *j);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_previous(UIntPtr sd_journal);
        // int sd_journal_previous(sd_journal *j);

        [DllImport("libsystemd.so.0", CharSet = CharSet.Ansi)]
        internal static extern int sd_journal_get_data(UIntPtr sd_journal, string field, ref IntPtr data, ref ulong length);
        // int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *l);
    }

    static void Main()
    {
        int result; // negative number on error
        UIntPtr j = new();

        result = Systemd.sd_journal_open(ref j, 0);
        Console.WriteLine($"result: {result}");  // return 0 on success

        result = Systemd.sd_journal_seek_head(j);
        Console.WriteLine($"result: {result}");  // return 0 on success

        ulong length;
        IntPtr data;

        while (true) {
            result = Systemd.sd_journal_step_one(j, 1);
            Console.WriteLine($"result: {result}");  // return the number of entries advanced/set back on success
            if (result < 1) break;

            data = new();
            length = 0;

            result = Systemd.sd_journal_get_data(j, "MESSAGE", ref data, ref length);
            Console.WriteLine($"result: {result} Message: {Marshal.PtrToStringAuto(data)} Length: {length}");
        }

        Systemd.sd_journal_close(j);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.