FEATURE:: Support for metrics collection - Prometheus and Open Telemetry (#3420)

* adding support for prometheus and grafana

* open telemetry

* lint fixes

* missing counter and telemetry standardization

---------

Co-authored-by: Henry <hzj94@hotmail.com>
This commit is contained in:
Vinod Kiran
2024-11-08 05:30:43 +05:30
committed by GitHub
parent 8466e1a0b0
commit fe03683f0c
22 changed files with 3493 additions and 54 deletions
+19 -2
View File
@@ -55,6 +55,7 @@ import { buildAgentGraph } from './buildAgentGraph'
import { getErrorMessage } from '../errors/utils'
import { ChatMessage } from '../database/entities/ChatMessage'
import { IAction } from 'flowise-components'
import { FLOWISE_METRIC_COUNTERS, FLOWISE_COUNTER_STATUS } from '../Interface.Metrics'
/**
* Build Chatflow
@@ -62,8 +63,8 @@ import { IAction } from 'flowise-components'
* @param {boolean} isInternal
*/
export const utilBuildChatflow = async (req: Request, isInternal: boolean = false): Promise<any> => {
const appServer = getRunningExpressApp()
try {
const appServer = getRunningExpressApp()
const chatflowid = req.params.id
const httpProtocol = req.get('x-forwarded-proto') || req.protocol
@@ -493,6 +494,10 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
flowGraph: getTelemetryFlowObj(nodes, edges)
})
appServer.metricsProvider.incrementCounter(
isInternal ? FLOWISE_METRIC_COUNTERS.CHATFLOW_PREDICTION_INTERNAL : FLOWISE_METRIC_COUNTERS.CHATFLOW_PREDICTION_EXTERNAL,
{ status: FLOWISE_COUNTER_STATUS.SUCCESS }
)
// Prepare response
// return the question in the response
// this is used when input text is empty but question is in audio format
@@ -507,6 +512,10 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
return result
} catch (e) {
appServer.metricsProvider.incrementCounter(
isInternal ? FLOWISE_METRIC_COUNTERS.CHATFLOW_PREDICTION_INTERNAL : FLOWISE_METRIC_COUNTERS.CHATFLOW_PREDICTION_EXTERNAL,
{ status: FLOWISE_COUNTER_STATUS.FAILURE }
)
logger.error('[server]: Error:', e)
if (e instanceof InternalFlowiseError && e.statusCode === StatusCodes.UNAUTHORIZED) {
throw e
@@ -533,8 +542,8 @@ const utilBuildAgentResponse = async (
shouldStreamResponse?: boolean,
uploadedFilesContent?: string
) => {
const appServer = getRunningExpressApp()
try {
const appServer = getRunningExpressApp()
const streamResults = await buildAgentGraph(
agentflow,
chatId,
@@ -599,6 +608,10 @@ const utilBuildAgentResponse = async (
type: isInternal ? ChatType.INTERNAL : ChatType.EXTERNAL,
flowGraph: getTelemetryFlowObj(nodes, edges)
})
appServer.metricsProvider.incrementCounter(
isInternal ? FLOWISE_METRIC_COUNTERS.AGENTFLOW_PREDICTION_INTERNAL : FLOWISE_METRIC_COUNTERS.AGENTFLOW_PREDICTION_EXTERNAL,
{ status: FLOWISE_COUNTER_STATUS.SUCCESS }
)
// Find the previous chat message with the same action id and remove the action
if (incomingInput.action && Object.keys(incomingInput.action).length) {
@@ -645,6 +658,10 @@ const utilBuildAgentResponse = async (
return undefined
} catch (e) {
logger.error('[server]: Error:', e)
appServer.metricsProvider.incrementCounter(
isInternal ? FLOWISE_METRIC_COUNTERS.AGENTFLOW_PREDICTION_INTERNAL : FLOWISE_METRIC_COUNTERS.AGENTFLOW_PREDICTION_EXTERNAL,
{ status: FLOWISE_COUNTER_STATUS.FAILURE }
)
throw new InternalFlowiseError(StatusCodes.INTERNAL_SERVER_ERROR, getErrorMessage(e))
}
}
+8 -10
View File
@@ -3,7 +3,6 @@ import * as fs from 'fs'
import * as path from 'path'
import { cloneDeep, omit } from 'lodash'
import { ICommonObject, IMessage, addArrayFilesToStorage, mapMimeTypeToInputField, mapExtToInputField } from 'flowise-components'
import telemetryService from '../services/telemetry'
import logger from '../utils/logger'
import {
buildFlow,
@@ -24,6 +23,7 @@ import { InternalFlowiseError } from '../errors/internalFlowiseError'
import { StatusCodes } from 'http-status-codes'
import { getErrorMessage } from '../errors/utils'
import { v4 as uuidv4 } from 'uuid'
import { FLOWISE_COUNTER_STATUS, FLOWISE_METRIC_COUNTERS } from '../Interface.Metrics'
/**
* Upsert documents
* @param {Request} req
@@ -190,16 +190,14 @@ export const upsertVector = async (req: Request, isInternal: boolean = false) =>
await appServer.AppDataSource.getRepository(UpsertHistory).save(upsertHistory)
}
await telemetryService.createEvent({
name: `vector_upserted`,
data: {
version: await getAppVersion(),
chatlowId: chatflowid,
type: isInternal ? ChatType.INTERNAL : ChatType.EXTERNAL,
flowGraph: getTelemetryFlowObj(nodes, edges),
stopNodeId
}
await appServer.telemetry.sendTelemetry('vector_upserted', {
version: await getAppVersion(),
chatlowId: chatflowid,
type: isInternal ? ChatType.INTERNAL : ChatType.EXTERNAL,
flowGraph: getTelemetryFlowObj(nodes, edges),
stopNodeId
})
appServer.metricsProvider.incrementCounter(FLOWISE_METRIC_COUNTERS.VECTORSTORE_UPSERT, { status: FLOWISE_COUNTER_STATUS.SUCCESS })
return upsertedResult['result'] ?? { result: 'Successfully Upserted' }
} catch (e) {