2017-10-12 9 views
0

App Engine StandardのリクエストログをBigQueryにエクスポートしています。BigQuery UDFでappengine_googleapis_com_request_log.protoPayload.lineを処理したい

Applicationによって出力されるログはprotoPayload.lineになっているので、UDFで処理しようとしました。

ただし、タイプの不一致エラーが原因で、クエリを実行できませんでした。 金型を一貫させるつもりですが、どうすれば解決できますか?

Error: No matching signature for function JS:LINE_COUNT for argument types: ARRAY<STRUCT<time TIMESTAMP, severity STRING, logMessage STRING, ...>>. Supported signature: LINE_COUNT(ARRAY<STRUCT<time TIMESTAMP, severity STRING, logMessage STRING, ...>>) at [3:3] 

問合せ:これについて

#standardSQL 
CREATE TEMPORARY FUNCTION LINE_COUNT(lines ARRAY<STRUCT<time TIMESTAMP, 
    severity STRING, 
    logMessage STRING, 
    sourceLocation STRUCT<file STRING, 
    line FLOAT64, 
    functionName STRING>>>) 
RETURNS FLOAT64 
LANGUAGE js AS """ 
var count = 0; 
for (var i = 0; i < lines.length; i++) { 
    count++; 
} 
return count; 
"""; 
SELECT 
LINE_COUNT(protoPayload.line) 
FROM 
`gaelog_from_bqstreaming.appengine_googleapis_com_request_log_*` 
WHERE 
_TABLE_SUFFIX BETWEEN FORMAT_DATE("%Y%m%d", 
    DATE_SUB(CURRENT_DATE(), 
    INTERVAL 1 DAY)) 
AND FORMAT_DATE("%Y%m%d", 
    CURRENT_DATE()) 
LIMIT 
1000 

答えて

3

どのように?

#standardSQL 
CREATE TEMPORARY FUNCTION LINE_COUNT(
    lines_json STRING) 
RETURNS FLOAT64 
LANGUAGE js AS """ 
var lines = JSON.Parse(lines_json); 
var count = 0; 
for (var i = 0; i < lines.length; i++) { 
    count++; 
} 
return count; 
"""; 
SELECT 
LINE_COUNT(TO_JSON_STRING(protoPayload.line)) 
FROM 
`gaelog_from_bqstreaming.appengine_googleapis_com_request_log_*` 
WHERE 
_TABLE_SUFFIX BETWEEN FORMAT_DATE("%Y%m%d", 
    DATE_SUB(CURRENT_DATE(), 
    INTERVAL 1 DAY)) 
AND FORMAT_DATE("%Y%m%d", 
    CURRENT_DATE()) 
LIMIT 
1000 

この種の計算にはJavaScriptは必要ありませんが、このタイプはすべて指定する必要はありません。あなたは高い課金層を必要としないので、通常は安くなるれ、直接SQLでそれを表現することができます。

SELECT 
    ARRAY_LENGTH(protoPayload.line) 
FROM 
`gaelog_from_bqstreaming.appengine_googleapis_com_request_log_*` 
WHERE 
_TABLE_SUFFIX BETWEEN FORMAT_DATE("%Y%m%d", 
    DATE_SUB(CURRENT_DATE(), 
    INTERVAL 1 DAY)) 
AND FORMAT_DATE("%Y%m%d", 
    CURRENT_DATE()) 
LIMIT 
1000 
+0

私はあなたのアドバイスで問題を解決しました!ありがとうございました! – sinmetal

0

のは最終的に私が作ったコードを作ってみましょう。 私はARRAYを検索してそれを抽出し、それを1つSTRUCTにしたいと思っていました。

#standardSQL 
    CREATE TEMPORARY FUNCTION GetQueueStats(lines_json STRING) 
    RETURNS STRUCT<email STRING, executed1Minute FLOAT64> 
    LANGUAGE js AS """ 
    var lines = JSON.parse(lines_json); 
    var result = { 
    email : '', 
    executed1Minute : 0 
    }; 
    lines.forEach(function(element, index, array) { 
    var emailPrefix = 'userEmail='; 
    var queueStats = 'TaskQueue.QueueStats:'; 
    if (element.logMessage.startsWith(emailPrefix)) { 
     result.email = element.logMessage.substring(emailPrefix.length); 
    } else if (element.logMessage.startsWith(queueStats)) { 
     var vj = element.logMessage.substring(queueStats.length); 
     var v = JSON.parse(vj); 
     result.executed1Minute = v.Executed1Minute; 
    } 
    }); 

    return result; 
"""; 
SELECT 
    insertId, 
    timestamp, 
    GetQueueStats(TO_JSON_STRING(protoPayload.line)) AS queueStats 
FROM 
    `appengine.appengine_googleapis_com_request_log_20171014` 
ORDER BY 
    timestamp DESC 
LIMIT 
    1000 
関連する問題