65.9K
CodeProject 正在变化。 阅读更多。
Home

Pantheios 后端介绍,第一部分:后端 API

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (12投票s)

2008年9月10日

BSD

7分钟阅读

viewsIcon

48397

downloadIcon

149

Pantheios 日志 API 库的后端 API 简介,附带一个简单的示例来说明这些概念

引言

如果您的日志记录需求很简单,那么 Pantheios 日志 API 库附带的、称为后端的标准传输组件可能就能满足您的需求。但如果您开发的程序需要高可用性、远程控制以及非简单系统通常需要的其他日志记录方面,那么您可能需要编写自定义后端。在这种情况下,深入理解 Pantheios 后端架构至关重要。本文是关于 Pantheios 后端的系列文章的第一篇,将介绍 API,说明如何编写一个非常简单的自定义后端,并讨论几个标准后端的功能。

在继续阅读之前,读者可能需要查看上一篇关于 设置项目和选择后端 的 Pantheios 教程文章。

后端 API

Pantheios 架构基于四个组件

  1. 应用程序层 - 应用程序代码中使用的类和函数,负责以统一的形式将日志语句的元素呈现给核心
  2. 核心 - 处理所有组件的初始化,并处理应用程序层提交的日志语句的处理
  3. 前端 - 定义进程标识,并仲裁是否由核心准备日志语句并将其发送到后端
  4. 后端 - 将准备好的日志语句发送到传输。

后端 API 由三个函数组成

// declared in pantheios/backend.h
int pantheios_be_init(
  char const* processIdentity
, void*       reserved
, void**      ptoken
);
void pantheios_be_uninit(
  void* token
);
int pantheios_be_logEntry(
  void*       feToken
, void*       beToken
, int         severity
, char const* entry
, size_t      cchEntry
);

pantheios_be_init()pantheios_be_uninit() 在初始化/取消初始化期间由核心调用。它们每个进程最多调用一次,并且(除非有人**极其**努力地做一些奇怪的事情)始终在主线程中调用。pantheios_be_logEntry() 在每个准备好的日志语句要发送时由核心调用,在进程的任何线程中。

一个简单的后端

以下假设代码显示了这些函数如何实现以将日志记录到 stdout。首先,pantheios_be_init()

// file: hypothetical_backend.c
#include <pantheios>
#include <pantheios>

#include <stdio.h>
#include <string.h>

int pantheios_be_init(
  char const* processIdentity
, void*       reserved
, void**      ptoken
)
{
  *ptoken = strdup(processIdentity);
  return (NULL == *ptoken)
    ? PANTHEIOS_INIT_RC_OUT_OF_MEMORY
    : PANTHEIOS_INIT_RC_SUCCESS;
}

此代码在初始化期间由 Pantheios 核心调用。它接收进程标识(由前端定义;我们将在未来的文章中介绍),如果需要,可以复制它,以及一个指向 void* 的指针,您可以在其中存储代表其状态的任何值。核心代表后端保存此值,并在后端 API 函数中使用,正如我们将看到的。

在这种情况下,我们将复制进程标识,并将其存储回 *ptoken。如果初始化成功,我们必须返回 PANTHEIOS_INIT_RC_SUCCESS。在这种情况下,唯一的替代方法是如果 string 无法复制,则失败,并返回指示性错误代码 PANTHEIOS_INIT_RC_OUT_OF_MEMORY。这两个错误代码都定义在 _pantheios/error_codes.h_ 中,以及一些代表常见(和一些不常见)初始化失败条件的许多其他代码。

(注意:此实现使用了非标准且因此不可移植的 C 函数 strdup() 作为此处的便利;请记住,这是一个**简单**的示例。)

在 Pantheios 中,所有初始化都成对进行,遵循以下规则

Pantheios 初始化规则:任何成功的初始化函数调用都将始终匹配相应的取消初始化函数调用。如果相应的初始化函数不成功,则永远不会调用取消初始化函数。

牢记这一点,我们可以非常简单地实现 pantheios_be_uninit() ,如下所示

void pantheios_be_uninit(
  void* token
)
{
  free(token);
}

传递的 token 与我们在 pantheios_be_init() 中的 *ptoken in 中写入的相同,我们可以直接释放它(假设我们的非标准 strdup() 使用 malloc() 进行分配)。

这样就只剩下日志函数 pantheios_be_logEntry()

int pantheios_be_logEntry(
  void*       feToken
, void*       beToken
, int         severity
, char const* entry
, size_t      cchEntry
)
{
  char const* processIdentity = (char const*)beToken;
  fprintf(stdout, "%s[%d]: %.*s\n", processIdentity, severity, (int)cchEntry, entry);
  return 0;
}

该函数接受五个参数

  1. feToken 是前端初始化状态。这使得自定义前端和后端能够相互通信。这将在未来的文章中讨论,在此不再进一步讨论。
  2. beToken 是我们我们在 pantheios_be_init() 中创建的 token。
  3. severity 是在应用程序代码中的日志语句中传递的严重性。
  4. entry 是指向以 null 结尾的 C 风格 string 的非 NULL 指针,其中包含语句文本。
  5. cchEntry 是指向 entry 的 C 风格字符串的长度。

提供 string 长度以及保证语句 string 以 null 结尾有点冗余。但是,这样做便于实现偏好一种形式或另一种形式的后端。例如,be.WindowsDebugger 后端使用 Windows API 函数 OutputDebugStringA(),该函数接受指向以 null 结尾的 C 风格 string 的指针。如果该后端必须分配一个 cchEntry + 1 的缓冲区,然后将 entry memcpy() 到其中,并在传递给 OutputDebugStringA() 之前附加一个 null 终止符,那将削弱 Pantheios 相当大的性能优势。反之亦然,对于需要显式长度的输出 API:必须对 entry 执行 strlen() 将同样是我们不想支付的成本。

在我们的例子中,我们将 processIdentity、severity 和语句传递给 fprintf(),它会将它们输出到标准输出,格式为:“<processIdentity>[<severity-code>]: <message>

由于核心代表后端维护状态,因此后端实现可以非常简单,并且可以像本例一样用 C 编写,而不是 C++。(几个标准后端和前端是用 C 编写的,部分是为了减少编译时间。)此外,状态可以比指向已分配内存块的指针复杂得多:在许多标准后端中,它是一个指向 C++ 对象的指针,该对象处理给定后端功能的相对复杂性。

Pantheios 的标准后端

当前 Pantheios 发行版提供的标准后端分为两类

  1. 具体后端
  2. 多路复用后端

多路复用后端允许将两个或多个具体后端组合起来,将日志输出发送到多个目标,例如控制台、Syslog 和文件。这些将在本系列的后续文章中详细讨论。

可用的具体后端有

  • be.ACE - 使用 Adaptive Communications Environment (ACE) 库的日志记录设施进行输出。这是 Pantheios 的卓越类型安全性和性能如何与具有更丰富日志记录设施的日志库相结合的一个示例。
  • be.COMErrorObject (仅限 Windows) - 输出到 COM 错误对象。在实现 COM 服务器时很有用,因为您可以在一个语句中将日志记录到文件/调试器并更新 COM 错误对象,COM 错误对象由自动化/脚本客户端使用。未来的文章将讨论如何做到这一点。
  • be.fail - 总是初始化失败。用于自动单元/组件测试
  • be.file - 输出到文件
  • be.fprintf - 输出到 stdout/stderr。这是上面简单示例的一个功能齐全、可移植的版本
  • be.null - 输出到“垃圾桶”。用于性能测试。
  • be.speech (当前仅限 Windows) - 以语音形式输出。
  • be.syslog (仅限 UNIX) - 通过发出 Syslog 数据包进行输出。
  • be.WindowsConsole (仅限 Windows) - 输出到 Windows 控制台,并对语句进行特定于严重性的颜色编码。
  • be.WindowsDebugger (仅限 Windows) - 使用 OutputDebugStringA() 输出到 Windows 调试器。这与其他后端结合使用非常有用,因为它允许从 IDE 中跟踪日志输出。
  • be.WindowsEventLog (仅限 Windows) - 输出到 Windows 事件日志。严重性级别被转换为事件日志类别(EVENTLOG_ERROR_TYPEEVENTLOG_WARNING_TYPEEVENTLOG_INFORMATION_TYPE)。
  • be.WindowsMessageBox (仅限 Windows) - 输出到 Windows 消息框。严重性级别被转换为消息框类型(MB_ICONERRORMB_ICONWARNINGMB_ICONINFORMATION)。

摘要

我们讨论了 Pantheios 后端 API,并查看了一个简单的 API 实现,涵盖了如何维护状态以及输出函数的详细信息。我们还简要讨论了标准后端及其用途。

在此基础上,本系列的后续文章将涵盖后端多路复用、与自定义前端的交互,以及深入探讨一些标准后端,作为实施自定义后端时应该做什么(以及不应该做什么)的指南。

Pantheios 的世界还有很多内容,在未来的文章中,我将解释更多功能,并介绍最佳实践,讨论为什么 Pantheios 提供 100% 类型安全以及无与伦比的性能

请随时在 SourceForge 上的 Pantheios 项目站点 的论坛上提问。

历史

  • 2008 年 9 月 9 日:初始版本
© . All rights reserved.