Repository: FlowiseAI/Flowise
File: packages/components/src/handler.ts (TypeScript)

Code before:
    } catch (err) {
        if (process.env.DEBUG === 'true') console.error(`Error setting up Arize tracer: ${err.message}`)
        return undefined
    }
}

interface PhoenixTracerOptions {
    apiKey: string
    baseUrl: string
    projectName: string
    sdkIntegration?: string
    sessionId?: string
    enableCallback?: boolean
}

function getPhoenixTracer(options: PhoenixTracerOptions): Tracer | undefined {
    const SEMRESATTRS_PROJECT_NAME = 'openinference.project.name'
    try {
        const parsed = new URL(options.baseUrl)
        const baseEndpoint = `${parsed.protocol}//${parsed.host}`
        const path = parsed.pathname.replace(/\/$/, '')
        const traceExporter = new ProtoOTLPTraceExporter({
            url: `${baseEndpoint}${path}/v1/traces`,
            headers: {
                api_key: options.apiKey || '',
                authorization: `Bearer ${options.apiKey || ''}`
            }
        })
        const tracerProvider = new NodeTracerProvider({
            resource: new Resource({
                [ATTR_SERVICE_NAME]: options.projectName,
                [ATTR_SERVICE_VERSION]: '1.0.0',
                [SEMRESATTRS_PROJECT_NAME]: options.projectName
            })
        })
        tracerProvider.addSpanProcessor(new SimpleSpanProcessor(traceExporter))
        if (options.enableCallback) {
            registerInstrumentations({
                instrumentations: []
            })
            const lcInstrumentation = new LangChainInstrumentation()
            lcInstrumentation.manuallyInstrument(CallbackManagerModule)
            tracerProvider.register()
        }
        return tracerProvider.getTracer(`phoenix-tracer-${uuidv4().toString()}`)
    } catch (err) {
        if (process.env.DEBUG === 'true') console.error(`Error setting up Phoenix tracer: ${err.message}`)
        return undefined
    }
}


Review comment (suggestion):
can you add a few tests for all of the following:

`http://localhost:6006`
`http://localhost:6006/v1/traces`
`https://app.phoenix.arize.com`
`https://app.phoenix.arize.com/v1/traces`
`https://app.phoenix.arize.com/s/my-space`
`https://app.phoenix.arize.com/s/my-space/v1/traces`
`https://my-phoenix.com/my-slug`
`https://my-phoenix.com/my-slug/v1/traces`

Code after:
    } catch (err) {
        if (process.env.DEBUG === 'true') console.error(`Error setting up Arize tracer: ${err.message}`)
        return undefined
    }
}

interface PhoenixTracerOptions {
    apiKey: string
    baseUrl: string
    projectName: string
    sdkIntegration?: string
    sessionId?: string
    enableCallback?: boolean
}

export function getPhoenixTracer(options: PhoenixTracerOptions): Tracer | undefined {
    const SEMRESATTRS_PROJECT_NAME = 'openinference.project.name'
    try {
        const parsedURL = new URL(options.baseUrl)
        const baseEndpoint = `${parsedURL.protocol}//${parsedURL.host}`

        // Remove trailing slashes
        let path = parsedURL.pathname.replace(/\/$/, '')

        // Remove any existing /v1/traces suffix
        path = path.replace(/\/v1\/traces$/, '')

        const exporterUrl = `${baseEndpoint}${path}/v1/traces`
        const exporterHeaders = {
            api_key: options.apiKey || '',
            authorization: `Bearer ${options.apiKey || ''}`
        }

        const traceExporter = new ProtoOTLPTraceExporter({
            url: exporterUrl,
            headers: exporterHeaders
        })
        const tracerProvider = new NodeTracerProvider({
            resource: new Resource({
                [ATTR_SERVICE_NAME]: options.projectName,
                [ATTR_SERVICE_VERSION]: '1.0.0',
                [SEMRESATTRS_PROJECT_NAME]: options.projectName
            })
        })
        tracerProvider.addSpanProcessor(new SimpleSpanProcessor(traceExporter))
        if (options.enableCallback) {
            registerInstrumentations({
                instrumentations: []
            })
            const lcInstrumentation = new LangChainInstrumentation()
            lcInstrumentation.manuallyInstrument(CallbackManagerModule)