日志
每个使用 C++、Java 或 Python 编写的 UDx 都有一个关联的 ServerInterface
实例。ServerInterface
类提供了写入 Vertica 日志的功能,C++ 实施还提供了在系统表中记录事件的功能。
将消息写入 Vertica 日志
可以使用 ServerInterface.log()
函数将消息写入到日志文件。此函数的工作方式与 printf()
相似,它使用已设置格式的字符串和一个可选值集,并将字符串写入到日志文件。将消息写入到的位置取决于函数在隔离模式还是非隔离模式下运行。
-
在非隔离模式下运行的函数会将其消息写入到编录目录中的
vertica.log
文件。 -
在隔离模式下运行的函数会将其消息写入到编录目录中名为
UDxLogs/UDxFencedProcesses.log
的日志文件。
为了帮助标识函数的输出,Vertica 会将绑定到 UDx 的 SQL 函数名称添加到日志消息中。
以下示例将记录 UDx 的输入值:
virtual void processBlock(ServerInterface &srvInterface,
BlockReader &argReader,
BlockWriter &resWriter)
{
try {
// While we have inputs to process
do {
if (argReader.isNull(0) || argReader.isNull(1)) {
resWriter.setNull();
} else {
const vint a = argReader.getIntRef(0);
const vint b = argReader.getIntRef(1);
<span class="code-input">srvInterface.log("got a: %d and b: %d", (int) a, (int) b);</span>
resWriter.setInt(a+b);
}
resWriter.next();
} while (argReader.next());
} catch(std::exception& e) {
// Standard exception. Quit.
vt_report_error(0, "Exception while processing block: [%s]", e.what());
}
}
@Override
public void processBlock(ServerInterface srvInterface,
BlockReader argReader,
BlockWriter resWriter)
throws UdfException, DestroyInvocation
{
do {
// Get the two integer arguments from the BlockReader
long a = argReader.getLong(0);
long b = argReader.getLong(1);
// Log the input values
<span class="code-input">srvInterface.log("Got values a=%d and b=%d", a, b);</span>
long result = a+b;
resWriter.setLong(result);
resWriter.next();
} while (argReader.next());
}
}
def processBlock(self, server_interface, arg_reader, res_writer):
server_interface.log("Python UDx - Adding 2 ints!")
while(True):
first_int = block_reader.getInt(0)
second_int = block_reader.getInt(1)
block_writer.setInt(first_int + second_int)
<span class="code-input">server_interface.log("Values: first_int is {} second_int is {}".format(first_int, second_int))</span>
block_writer.next()
if not block_reader.next():
break
log()
函数在日志文件中生成条目,如下所示:
$ tail /home/dbadmin/py_db/v_py_db_node0001_catalog/UDxLogs/UDxFencedProcesses.log
07:52:12.862 [Python-v_py_db_node0001-7524:0x206c-40575] 0x7f70eee2f780 PythonExecContext::processBlock
07:52:12.862 [Python-v_py_db_node0001-7524:0x206c-40575] 0x7f70eee2f780 [UserMessage] add2ints - Python UDx - Adding 2 ints!
07:52:12.862 [Python-v_py_db_node0001-7524:0x206c-40575] 0x7f70eee2f780 [UserMessage] add2ints - Values: first_int is 100 second_int is 100
有关查看 Vertica 日志文件的详细信息,请参阅监控日志文件。
将消息写入 UDX_EVENTS 表(仅限 C++)
在 C++ API 中,除了写入日志之外,您还可以将消息写入 UDX_EVENTS 系统表。写入系统表之后,您可以将来自所有节点的事件收集至一个位置中。
可以使用 ServerInterface.logEvent()
函数将消息写入此表。该函数将提取一个实参和一个映射。映射作为 Flex VMap 写入表的 RAW 列。以下示例显示 Parquet 导出器如何创建和记录此映射。
// Log exported parquet file details to v_monitor.udx_events
std::map<std::string, std::string> details;
details["file"] = escapedPath;
details["created"] = create_timestamp_;
details["closed"] = close_timestamp_;
details["rows"] = std::to_string(num_rows_in_file);
details["row_groups"] = std::to_string(num_row_groups_in_file);
details["size_mb"] = std::to_string((double)outputStream->Tell()/(1024*1024));
srvInterface.logEvent(details);
您可以从 VMap 中选择单个字段,如下例所示。
=> SELECT __RAW__['file'] FROM UDX_EVENTS;
__RAW__
-----------------------------------------------------------------------------
/tmp/export_tmpzLkrKq3a/450c4213-v_vmart_node0001-139770732459776-0.parquet
/tmp/export_tmpzLkrKq3a/9df1c797-v_vmart_node0001-139770860660480-0.parquet
(2 rows)
或者,您可以定义一个视图,以便像列一样更轻松地直接查询字段。有关示例,请参阅 监控导出。