C言語のロギングとランタイム情報
この例では、次のファイル名を使用している:log.c
コード
この例のコードは、一般的には使用されないかもしれない機能を探っている。 ログの記録は、AEの実行を追跡するのに役立つ。 使用するには、AEがログマスクで登録され、nzudxdbgを介してロギングが有効になっていなければならない。 NPS システムが起動したウィンドウでシステム・ログ・メッセージを受信するには、NPS を'-i'オプションで起動する必要がある(例えば、'nzstart-i') これにより、NPSプロセスは端末に接続されたままとなる。 ランタイム情報は、データスライス数、SPU 数、実行場所など、NPS システムに関する統計情報を提供する。
#include <stdio.h>
#include <stdlib.h>
#include "nzaeapis.h"
static int run(NZAE_HANDLE h);
int main(int argc, char * argv[])
{
if (nzaeIsLocal())
{
NzaeInitialization arg;
memset(&arg, 0, sizeof(arg));
arg.ldkVersion = NZAE_LDK_VERSION;
if (nzaeInitialize(&arg))
{
fprintf(stderr, "initialization failed\n");
return -1;
}
run(arg.handle);
nzaeClose(arg.handle);
}
else {
NZAECONPT_HANDLE hConpt = nzaeconptCreate();
if (!hConpt)
{
fprintf(stderr, "error creating connection point\n");
fflush(stderr);
return -1;
}
const char * conPtName = nzaeRemprotGetRemoteName();
if (!conPtName)
{
fprintf(stderr, "error getting connection point name\n");
fflush(stderr);
exit(-1);
}
if (nzaeconptSetName(hConpt, conPtName))
{
fprintf(stderr, "error setting connection point name\n");
fflush(stderr);
nzaeconptClose(hConpt);
return -1;
}
NzaeremprotInitialization args;
memset(&args, 0, sizeof(args));
args.ldkVersion = NZAE_LDK_VERSION;
args.hConpt = hConpt;
if (nzaeRemprotCreateListener(&args))
{
fprintf(stderr, "unable to create listener - %s\n", \
args.errorMessage);
fflush(stderr);
nzaeconptClose(hConpt);
return -1;
}
NZAEREMPROT_HANDLE hRemprot = args.handle;
NzaeApi api;
int i;
for (i = 0; i < 5; i++)
{
if (nzaeRemprotAcceptApi(hRemprot, &api))
{
fprintf(stderr, "unable to accept API - %s\n", \
nzaeRemprotGetLastErrorText(hRemprot));
fflush(stderr);
nzaeconptClose(hConpt);
nzaeRemprotClose(hRemprot);
return -1;
}
if (api.apiType != NZAE_API_FUNCTION)
{
fprintf(stderr, "unexpected API returned\n");
fflush(stderr);
nzaeconptClose(hConpt);
nzaeRemprotClose(hRemprot);
return -1;
}
printf("testcapi: accepted a remote request\n");
fflush(stdout);
run(api.handle.function);
}
nzaeRemprotClose(hRemprot);
nzaeconptClose(hConpt);
}
return 0;
}
static void validateRuntime(NZAE_HANDLE handle, NzaeRuntime *aeRun, int64_t \
*args, int type)
{
// argss:
// dataslice, transaction, hardware, numslices, numspus, locus
int64_t dataslice = args[0];
int64_t txid = args[1];
int64_t hwid = args[2];
int64_t nslices = args[3];
int64_t nspus = args[4];
int64_t locus = args[5];
char buf[1024];
if (locus != (int64_t)aeRun->locus)
{
sprintf(buf, "test fails: 1\n");
nzaeLog(handle,NZAE_LOG_DEBUG, buf);
}
if (aeRun->suggestedMemoryLimit != 123)
{
sprintf(buf, "test fails: 7 \n");
nzaeLog(handle,NZAE_LOG_DEBUG, buf);
}
if (aeRun->userQuery == false)
{
sprintf(buf, "test fails: 8 \n");
nzaeLog(handle,NZAE_LOG_DEBUG, buf);
}
if (type != (int64_t)aeRun->adapterType)
{
sprintf(buf, "test fails: 9 \n");
nzaeLog(handle,NZAE_LOG_DEBUG, buf);
}
if (locus == (int64_t)NZAE_LOCUS_POSTGRES)
{
return;
}
if (dataslice != (int64_t)aeRun->dataSliceId)
{
sprintf(buf, "test fails: 2 \n");
nzaeLog(handle,NZAE_LOG_DEBUG, buf);
}
if (txid != 0 && txid != (int64_t)aeRun->transactionId)
{
sprintf(buf, "test fails: 3 \n");
nzaeLog(handle,NZAE_LOG_DEBUG, buf);
}
if (hwid != (int64_t)aeRun->hardwareId)
{
sprintf(buf, "test fails: 4 \n");
nzaeLog(handle,NZAE_LOG_DEBUG, buf);
}
if (nslices != (int64_t)aeRun->numberDataSlices)
{
sprintf(buf, "test fails: 5 \n");
nzaeLog(handle,NZAE_LOG_DEBUG, buf);
}
if (nspus != (int64_t)aeRun->numberSpus)
{
sprintf(buf, "test fails: 6 \n");
nzaeLog(handle,NZAE_LOG_DEBUG, buf);
}
}
static int run(NZAE_HANDLE h)
{
NzaeMetadata metadata;
if (nzaeGetMetadata(h, &metadata))
{
fprintf(stderr, "get metadata failed\n");
return -1;
}
#define CHECK(value) \
{ \
NzaeRcCode rc = value; \
if (rc) \
{ \
const char * format = "%s in %s at %d"; \
fprintf(stderr, format, \
nzaeGetLastErrorText(h), __FILE__, __LINE__); \
nzaeUserError(h, format, \
nzaeGetLastErrorText(h), __FILE__, __LINE__); \
exit(-1); \
} \
}
for (;;)
{
int64_t ar[6];
int i;
double result = 0;
NzaeRcCode rc = nzaeGetNext(h);
if (rc == NZAE_RC_END)
{
break;
}
NzudsData * input = NULL;
for (i=0; i < 6; i++) {
CHECK(nzaeGetInputColumn(h, i, &input));
if (input->type == NZUDSUDX_INT32)
{
ar[i] = *input->data.pInt32;
}
else if (input->type == NZUDSUDX_INT64)
{
ar[i] = *input->data.pInt64;
}
}
NzaeRuntime aeRun;
nzaeGetRuntime(h,&aeRun);
validateRuntime(h, &aeRun, ar, NZAE_ADAPTER_UDTF);
CHECK(nzaeSetOutputString(h, 0, "done"));
CHECK(nzaeOutputResult(h));
}
nzaeDone(h);
return 0;
}
コンパイル
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language system --version 3 \
--template compile log.c --exe log登録
memオプションと-maskオプションを使ってサンプルを登録する。 maskオプションはDEBUGのロギングを有効にし、-memオプションはメモリーのランタイム情報を設定する。
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --language system --version 3 \
--template udtf --exe log \
--sig "runtime_c(int8,int8,int8,int8,int8,int8)" \
--return "table(output varchar(100))" --mask debug --mem 123
実行中
実行する前に、'nzudxdbg:実行してロギングを有効にする。
nzudxdbg
Processing 1 spus
.
done
Processing host
done
そしてSQLを実行する:
SELECT * FROM TABLE WITH FINAL(runtime_c(1,1,1,1,1,1));
OUTPUT
--------
done
(1 row)
NPS システムのログは、NPS システムが起動されたウィンドウに表示されます:
05-03-10 15:03:12 (dbos.18728) [d,udx ] test fails: 2
05-03-10 15:03:12 (dbos.18728) [d,udx ] test fails: 3
05-03-10 15:03:12 (dbos.18728) [d,udx ] test fails: 4
これらのケースでは、指定された引数がランタイムと一致しなかったので、これは期待された出力である。