0

我使用 rsyslog 并想从我的应用程序中记录一些操作。日志记录工作正常,日志文件将被正确创建。

我格式化了输出,因为我想看到programname

rsyslog.conf:

$template usermsg,"%TIMESTAMP% %HOSTNAME% %programname% \n"
$ActionFileDefaultTemplate usermsg

输出:

Oct 14 16:28:25 box #001

我总是得到#001programname尽管它应该是“计算器”。有谁知道如何解决这个问题?

我在我的应用程序中创建了一个记录器实例:

//ident = "计算器"

//facility= LOG_USER /* (1<<3) 随机用户级消息 */

openlog(ident.c_str(), 0, 设施);

4

1 回答 1

1

大胆猜测,ident它是一个有限范围的 C++ 字符串对象——即它很可能是一个局部变量c_str(),并且充其量是一个临时有效的指针。

该指针必须在应用程序的整个运行过程中保持有效;openlog 在手册中明确说明了这一点:

openlog() 调用中的参数 ident 可能按原样存储。因此,如果它指向的字符串被更改,syslog() 可能会开始在更改后的字符串之前添加,并且如果它指向的字符串不再存在,则结果是不确定的。最可移植的是使用字符串常量。

gnu.org 联机帮助页提到:

请注意,字符串指针 ident 将由 Syslog 例程在内部保留。您不能释放 ident 指向的内存。传递对自动变量的引用也是危险的,因为离开范围意味着结束变量的生命周期。如果要更改 ident 字符串,必须再次调用 openlog;覆盖 ident 指向的字符串不是线程安全的。

所以最有可能的是字符串变量超出范围,你最终得到一个指向某个随机字符串的指针,在你的情况下恰好是#001.

解决方案有很多,但它们都涉及确保c_str()在应用程序运行期间不会更改指向的数据。

于 2013-11-23T00:30:52.293 回答