Skip to content

Commit b026671

Browse files
authored
feat: Enable Tracing Support For Self-Hosted & Cloud Phoenix Instance (#5114)
* feat: Enable Tracing Support For Self-Hosted & Cloud Phoenix Instance * feat: Add Testcase For Phoenix Exporter URL Handling
1 parent 23cb5f7 commit b026671

File tree

2 files changed

+70
-5
lines changed

2 files changed

+70
-5
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { getPhoenixTracer } from './handler'
2+
3+
jest.mock('@opentelemetry/exporter-trace-otlp-proto', () => {
4+
return {
5+
ProtoOTLPTraceExporter: jest.fn().mockImplementation((args) => {
6+
return { args }
7+
})
8+
}
9+
})
10+
11+
import { OTLPTraceExporter as ProtoOTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'
12+
13+
describe('URL Handling For Phoenix Tracer', () => {
14+
const apiKey = 'test-api-key'
15+
const projectName = 'test-project-name'
16+
17+
const makeOptions = (baseUrl: string) => ({
18+
baseUrl,
19+
apiKey,
20+
projectName,
21+
enableCallback: false
22+
})
23+
24+
beforeEach(() => {
25+
jest.clearAllMocks()
26+
})
27+
28+
const cases: [string, string][] = [
29+
['http://localhost:6006', 'http://localhost:6006/v1/traces'],
30+
['http://localhost:6006/v1/traces', 'http://localhost:6006/v1/traces'],
31+
['https://app.phoenix.arize.com', 'https://app.phoenix.arize.com/v1/traces'],
32+
['https://app.phoenix.arize.com/v1/traces', 'https://app.phoenix.arize.com/v1/traces'],
33+
['https://app.phoenix.arize.com/s/my-space', 'https://app.phoenix.arize.com/s/my-space/v1/traces'],
34+
['https://app.phoenix.arize.com/s/my-space/v1/traces', 'https://app.phoenix.arize.com/s/my-space/v1/traces'],
35+
['https://my-phoenix.com/my-slug', 'https://my-phoenix.com/my-slug/v1/traces'],
36+
['https://my-phoenix.com/my-slug/v1/traces', 'https://my-phoenix.com/my-slug/v1/traces']
37+
]
38+
39+
it.each(cases)('baseUrl %s - exporterUrl %s', (input, expected) => {
40+
getPhoenixTracer(makeOptions(input))
41+
expect(ProtoOTLPTraceExporter).toHaveBeenCalledWith(
42+
expect.objectContaining({
43+
url: expected,
44+
headers: expect.objectContaining({
45+
api_key: apiKey,
46+
authorization: `Bearer ${apiKey}`
47+
})
48+
})
49+
)
50+
})
51+
})

packages/components/src/handler.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Logger } from 'winston'
2+
import { URL } from 'url'
23
import { v4 as uuidv4 } from 'uuid'
34
import { Client } from 'langsmith'
45
import CallbackHandler from 'langfuse-langchain'
@@ -91,14 +92,27 @@ interface PhoenixTracerOptions {
9192
enableCallback?: boolean
9293
}
9394

94-
function getPhoenixTracer(options: PhoenixTracerOptions): Tracer | undefined {
95+
export function getPhoenixTracer(options: PhoenixTracerOptions): Tracer | undefined {
9596
const SEMRESATTRS_PROJECT_NAME = 'openinference.project.name'
9697
try {
98+
const parsedURL = new URL(options.baseUrl)
99+
const baseEndpoint = `${parsedURL.protocol}//${parsedURL.host}`
100+
101+
// Remove trailing slashes
102+
let path = parsedURL.pathname.replace(/\/$/, '')
103+
104+
// Remove any existing /v1/traces suffix
105+
path = path.replace(/\/v1\/traces$/, '')
106+
107+
const exporterUrl = `${baseEndpoint}${path}/v1/traces`
108+
const exporterHeaders = {
109+
api_key: options.apiKey || '',
110+
authorization: `Bearer ${options.apiKey || ''}`
111+
}
112+
97113
const traceExporter = new ProtoOTLPTraceExporter({
98-
url: `${options.baseUrl}/v1/traces`,
99-
headers: {
100-
api_key: options.apiKey
101-
}
114+
url: exporterUrl,
115+
headers: exporterHeaders
102116
})
103117
const tracerProvider = new NodeTracerProvider({
104118
resource: new Resource({

0 commit comments

Comments
 (0)