Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support log_level #393

Merged
merged 1 commit into from
Jan 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/smartapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,18 @@ paths:
required: true
schema:
type: string
- description: option to override original query log level
in: query
name: log_level
required: false
schema:
type: string
description: Logging level
enum:
- ERROR
- WARNING
- INFO
- DEBUG
responses:
'200':
description: Returns status. If successfully completed, it will return a TRAPI Response object
Expand Down
17 changes: 13 additions & 4 deletions src/controllers/async/asyncquery.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ exports.asyncquery = async (req, res, next, queueData, queryQueue) => {
}
}

async function storeQueryResponse(jobID, response) {
async function storeQueryResponse(jobID, response, logLevel = null) {
const unlock = await redisClient.lock(`asyncQueryResult:lock:${jobID}`);
try {
const defaultExpirySeconds = String(7 * 24 * 60 * 60); // one 7-day week
Expand Down Expand Up @@ -77,19 +77,23 @@ async function storeQueryResponse(jobID, response) {
// register all keys so they can be properly retrieved
await redisClient.setAsync(`asyncQueryResult:entries:${jobID}`, JSON.stringify(entries));
await redisClient.expireAsync(`asyncQueryResult:entries:${jobID}`, process.env.ASYNC_COMPLETED_EXPIRE_TIME || defaultExpirySeconds);
// remember log_level setting from original query
await redisClient.setAsync(`asyncQueryResult:logLevel:${jobID}`, JSON.stringify(logLevel));
await redisClient.expireAsync(`asyncQueryResult:logLevel:${jobID}`, process.env.ASYNC_COMPLETED_EXPIRE_TIME || defaultExpirySeconds);

} finally {
unlock();
}
}

exports.getQueryResponse = async jobID => {
exports.getQueryResponse = async (jobID, logLevel = null) => {
const unlock = await redisClient.lock(`asyncQueryResult:lock${jobID}`);
try {
const entries = await redisClient.getAsync(`asyncQueryResult:entries:${jobID}`);
if (!entries) {
return null;
}
const originalLogLevel = await redisClient.getAsync(`asyncQueryResult:logLevel:${jobID}`);
const values = await Promise.all(JSON.parse(entries).map(async (key) => {
const value = await new Promise(async (resolve) => {
const msgDecoded = Object.entries(await redisClient.hgetallAsync(`asyncQueryResult:${jobID}:${key}`))
Expand All @@ -104,6 +108,11 @@ exports.getQueryResponse = async jobID => {
return [key, value];
}));
const response = Object.fromEntries(values);
if (response.logs && logLevel) {
utils.filterForLogLevel(response, logLevel);
} else if (response.logs && originalLogLevel) {
utils.filterForLogLevel(response, originalLogLevel);
}
return response ? response : undefined;
} finally {
unlock();
Expand All @@ -117,10 +126,10 @@ exports.asyncqueryResponse = async (handler, callback_url, jobID = null, jobURL
await handler.query();
response = handler.getResponse();
if (jobURL) {
response.logs.unshift(new LogEntry('DEBUG', null, `job status available at: ${jobURL}`).getLog());
response.logs.unshift(new LogEntry('INFO', null, `job status available at: ${jobURL}`).getLog());
}
if (jobID) {
await storeQueryResponse(jobID, response);
await storeQueryResponse(jobID, response, handler.options.logLevel);
}
} catch (e) {
console.error(e)
Expand Down
5 changes: 3 additions & 2 deletions src/controllers/async/processors/async_v1.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ const predicatesPath = path.resolve(__dirname, process.env.STATIC_PATH ? `${proc
const utils = require("../../../utils/common");
const { asyncqueryResponse } = require("../asyncquery");

async function jobToBeDone(jobID, queryGraph, caching, workflow, callback_url, jobURL = null) {
async function jobToBeDone(jobID, queryGraph, caching, workflow, callback_url, jobURL = null, logLevel = null) {
utils.validateWorkflow(workflow);
const handler = new TRAPIGraphHandler.TRAPIQueryHandler(
{ apiList: config.API_LIST, caching: caching },
{ apiList: config.API_LIST, caching: caching, logLevel: logLevel },
smartAPIPath,
predicatesPath,
);
Expand All @@ -26,5 +26,6 @@ module.exports = async job => {
job.data.workflow,
job.data.callback_url,
job.data.url,
job.data.logLevel,
);
};
22 changes: 12 additions & 10 deletions src/controllers/async/processors/async_v1_by_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ const predicatesPath = path.resolve(__dirname, process.env.STATIC_PATH ? `${proc
const { asyncqueryResponse } = require('../asyncquery');
const utils = require("../../../utils/common");

async function jobToBeDone(jobID, queryGraph, smartAPIID, caching, enableIDResolution, workflow, callback_url, jobURL = null){
async function jobToBeDone(jobID, queryGraph, smartAPIID, caching, enableIDResolution, workflow, callback_url, jobURL = null, logLevel = null){
utils.validateWorkflow(workflow);
const handler = new TRAPIGraphHandler.TRAPIQueryHandler(
{
smartAPIID,
caching,
logLevel,
enableIDResolution
},
smartAPIPath,
Expand All @@ -23,13 +24,14 @@ async function jobToBeDone(jobID, queryGraph, smartAPIID, caching, enableIDResol

module.exports = async (job) => {
return await jobToBeDone(
job.data.id,
job.data.queryGraph,
job.data.smartAPIID,
job.data.caching,
job.data.enableIDResolution,
job.data.workflow,
job.data.callback_url,
job.data.url,
);
job.data.id,
job.data.queryGraph,
job.data.smartAPIID,
job.data.caching,
job.data.enableIDResolution,
job.data.workflow,
job.data.callback_url,
job.data.url,
job.data.logLevel,
);
}
4 changes: 3 additions & 1 deletion src/controllers/async/processors/async_v1_by_team.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ const predicatesPath = path.resolve(__dirname, process.env.STATIC_PATH ? `${proc
const { asyncqueryResponse } = require('../asyncquery');
const utils = require("../../../utils/common");

async function jobToBeDone(jobID, queryGraph, teamName, caching, enableIDResolution, workflow, callback_url, jobURL = null){
async function jobToBeDone(jobID, queryGraph, teamName, caching, enableIDResolution, workflow, callback_url, jobURL = null, logLevel = null){
utils.validateWorkflow(workflow);
const handler = new TRAPIGraphHandler.TRAPIQueryHandler(
{
teamName,
caching,
logLevel,
enableIDResolution
},
smartAPIPath,
Expand All @@ -31,5 +32,6 @@ module.exports = async (job) => {
job.data.workflow,
job.data.callback_url,
job.data.url,
job.data.logLevel,
);
};
3 changes: 2 additions & 1 deletion src/routes/v1/asyncquery_v1.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class V1RouteAsyncQuery {
queryGraph: req.body.message.query_graph,
workflow: req.body.workflow,
callback_url: req.body.callback_url || req.body['callback'],
caching: req.query.caching
caching: req.query.caching,
logLevel: req.body.log_level,
}
await asyncquery(req, res, next, queueData, queryQueue)
});
Expand Down
1 change: 1 addition & 0 deletions src/routes/v1/asyncquery_v1_by_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class V1RouteAsyncQueryByAPI {
queryGraph: req.body.message.query_graph,
smartAPIID: req.params.smartapi_id,
caching: req.query.caching,
logLevel: req.body.log_level,
workflow: req.body.workflow,
callback_url: req.body.callback_url || req.body['callback'],
enableIDResolution
Expand Down
1 change: 1 addition & 0 deletions src/routes/v1/asyncquery_v1_by_team.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class V1RouteAsyncQueryByTeam {
queryGraph: queryGraph,
teamName: req.params.team_name,
caching: req.query.caching,
logLevel: req.body.log_level,
workflow: req.body.workflow,
callback_url: req.body.callback_url || req.body['callback'],
enableIDResolution
Expand Down
3 changes: 2 additions & 1 deletion src/routes/v1/check_query_status.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const redisClient = require('../../utils/cache/redis-client');
const { getQueryQueue } = require('../../controllers/async/asyncquery_queue');
const { getQueryResponse } = require('../../controllers/async/asyncquery');
const lz4 = require('lz4');
const utils = require('../../utils/common');

let queryQueue;

Expand Down Expand Up @@ -67,7 +68,7 @@ class VCheckQueryStatus {
}
let returnvalue = job.returnvalue;
if (returnvalue?.response && !returnvalue?.response?.error) {
const storedResponse = await getQueryResponse(id);
const storedResponse = await getQueryResponse(id, req.query.log_level);
if (storedResponse) {
returnvalue.response = storedResponse;
} else {
Expand Down
4 changes: 3 additions & 1 deletion src/routes/v1/query_v1.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ class V1RouteQuery {
handler.setQueryGraph(queryGraph);
await handler.query();

return taskResponse(handler.getResponse());
const response = handler.getResponse();
utils.filterForLogLevel(response, req.body.log_level);
return taskResponse(response);
} catch (error) {
return taskError(error);
}
Expand Down
4 changes: 3 additions & 1 deletion src/routes/v1/query_v1_by_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ class RouteQueryV1ByAPI {
);
handler.setQueryGraph(queryGraph);
await handler.query();
return taskResponse(handler.getResponse());
const response = handler.getResponse();
utils.filterForLogLevel(response, req.body.log_level);
return taskResponse(response);
} catch (error) {
return taskError(error);
}
Expand Down
4 changes: 3 additions & 1 deletion src/routes/v1/query_v1_by_team.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ class RouteQueryV1ByTeam {
);
handler.setQueryGraph(queryGraph);
await handler.query();
taskResponse(handler.getResponse());
const response = handler.getResponse();
utils.filterForLogLevel(response, req.body.log_level);
taskResponse(response);
} catch (error) {
taskError(error);
}
Expand Down
14 changes: 14 additions & 0 deletions src/utils/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,17 @@ exports.stringIsAValidUrl = (s) => {
return false;
}
};

exports.filterForLogLevel = (response, logLevel) => {
const logLevels = {
ERROR: 3,
WARNING: 2,
INFO: 1,
DEBUG: 0
}
if (logLevel && Object.keys(logLevels).includes(logLevel)) {
response.logs = response.logs.filter(log => {
return logLevels[log.level] >= logLevels[logLevel]
});
}
}