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

これらのケースでは、指定された引数がランタイムと一致しなかったので、これは期待された出力である。