Yapılandırma
Her ayar bir seçenektir ve her seçeneğin aynı anlama gelen bir ortam değişkeni vardır. Komut satırına sığmayacak kadar yapılı olan birkaç ayar tek bir JSON dosyasında durur. Bu sayfa hepsini anlatır.
Aynı şeyi söylemenin iki yolu
mcpd'yi hiçbir argüman vermeden çalıştırın, iş görür:
0.0.0.0:4317 adresini dinler, veriyi ./mcpd.db
içinde tutar, sırları maskeler ve her trace'i sonsuza kadar saklar. Aşağıdaki
her şey bu kararlardan birini değiştirir.
Bir seçenek her zaman kendi ortam değişkenini yener. İkisi de geneldir, yani bir alt komuttan önce de sonra da kabul edilir.
Referans
| Seçenek | Değişken | Varsayılan |
|---|---|---|
--listen | MCPD_LISTEN | 0.0.0.0:4317 |
--data | MCPD_DATA | ./mcpd.db |
--project | MCPD_PROJECT | default |
--retention-days | MCPD_RETENTION_DAYS | ayarsız: her şey saklanır |
--ingest-key | MCPD_INGEST_KEYS | yok: alım açıktır |
--read-key | MCPD_READ_KEYS | yok: okuma açıktır |
--write-key | MCPD_WRITE_KEYS | yok: alım anahtarları kabul edilir |
--admin-key | MCPD_ADMIN_KEYS | yok: okuma anahtarları kabul edilir |
--execute-key | MCPD_EXECUTE_KEYS | yok: yazma anahtarları kabul edilir |
--worker-key | MCPD_WORKER_KEYS | yok: yazma anahtarları kabul edilir |
--runs-data | MCPD_RUNS_DATA | uzantısından önce .runs eklenmiş --data yolu |
--trusted-identity-header | MCPD_TRUSTED_IDENTITY_HEADER | yok: hiçbir özne kaydedilmez |
--trusted-proxy-cidr | MCPD_TRUSTED_PROXY_CIDRS | yok: hiçbir adres o başlığı ayarlayamaz |
--sample | MCPD_SAMPLE | ayarsız: her trace saklanır |
--quota-per-minute | MCPD_QUOTA_PER_MINUTE | ayarsız: tavan yok |
--no-redact | MCPD_NO_REDACT | kapalı: maskeleme açıktır |
--redact-key | MCPD_REDACT_KEY | yerleşik bir anahtar, herkese açık |
--redact-key-contains | MCPD_REDACT_KEY_CONTAINS | yok: yalnızca yerleşik kurallar |
--redact-max-string | MCPD_REDACT_MAX_STRING | 128 KiB |
--cors-origin | MCPD_CORS_ORIGINS | yok: yalnızca aynı köken |
--request-timeout-seconds | MCPD_REQUEST_TIMEOUT_SECONDS | 30 |
--max-body-bytes | MCPD_MAX_BODY_BYTES | 33554432, yani 32 MiB |
--max-batch-signals | MCPD_MAX_BATCH_SIGNALS | 10000 |
--log-format | MCPD_LOG_FORMAT | text |
--clickhouse-url | MCPD_CLICKHOUSE_URL | kapalı: gömülü dosya kullanılır |
--clickhouse-database | MCPD_CLICKHOUSE_DATABASE | mcpd |
--clickhouse-user | MCPD_CLICKHOUSE_USER | yok |
--clickhouse-password | MCPD_CLICKHOUSE_PASSWORD | yok |
--postgres-url | MCPD_POSTGRES_URL | kapalı: gömülü dosya kullanılır |
--config-file | MCPD_CONFIG_FILE | yok |
--forward-endpoint | MCPD_FORWARD_ENDPOINT | kapalı: hiçbir şey iletilmez |
--forward-header | MCPD_FORWARD_HEADERS | yok |
| yok | MCPD_LOG | mcpd=info,mcpd_server=info,tower_http=warn |
--listen
Bağlanılacak adres. Tek bir port OTLP uçlarını, yerel alım ucunu, sorgu API'sini, yoklamaları, metrikleri ve arayüzü birlikte sunar; dolayısıyla mcpd'nin tek adresi budur.
Bir geri döngü adresine bağlanmak sessiz seçimdir: mcpd, açık alım için
yalnızca bağlandığı adres geri döngü değilse uyarır. Hiç anahtar
ayarlanmadan 0.0.0.0 üzerinde başlatıldığında açılışta iki kez
uyarır, biri alım biri okuma için.
--data
SQLite dosyasının yolu. Üst dizinler yoksa oluşturulur. Arkasında hiçbir şey
bırakmayan bir depo için :memory: verin; bu bir gösterim veya
test için doğru, yarın bakmak isteyeceğiniz bir şey için yanlıştır.
--project
Gönderen bir proje adı vermediğinde sinyalin düştüğü proje. Proje kiracılık
sınırıdır: her sorgu tek bir projeyle sınırlıdır. Saklama taraması hem bu
proje hem de projects bloğundaki her proje için çalışır; ikisine
de girmeyen bir proje hiç budanmaz, ki gönderenleriniz kendi projelerini
adlandırıyorsa bu önemlidir.
--retention-days
Bu kadar günden eski sinyalleri silin. Ayarsız bırakmak her şeyi saklar; bir dizüstü için doğru varsayılan budur ve başka her yerde bilerek verilmesi gereken bir karardır.
Pencere 1 ile 36500 gün arasındadır; bir projenin
retention_days değeri için de aynısı geçerlidir. Sıfır, saklama
yok diye okunmaz, başlangıçta reddedilir: kesim noktasını şimdiye koyardı ve
ilk geçiş açılışta çalıştığı için projenin tüm sinyallerini silerdi. Her
şeyi tutmak için ayarı hiç vermeyin.
Tarama sorgu anında değil saatlik bir zamanlayıcıyla çalışır, böylece büyük bir silme hiçbir zaman kullanıcının isteğinin içine düşmez. Span'ler, trace'ler, loglar ve metrikler mcpd'nin onları aldığı ana göre kesilir; puanlar, geri bildirimler ve yön notları kendi zaman damgalarına göre. Satırları silmek dosyayı küçültmez. Bakınız İşletme.
--ingest-key, --read-key, --write-key, --admin-key, --execute-key ve --worker-key
Altı kapsam, çünkü taşıdıkları risk gerçekten farklıdır. Her uç, ihtiyaç
duyduğu kapsamı spec/mcpd.spec.json içinde bildirir, arkasındaki
işleyici de aynı şekilde etiketlenir ve make check ikisini
karşılaştırır; yani burada belgelenen kapsam, çalışan sunucunun uyguladığı
kapsamdır.
| Kapsam | Ayarlandığı yer | Neyi açar |
|---|---|---|
ingest | --ingest-key | Dört alım ucunu. Hiçbir şey okumaz. |
read | --read-key | Sorgu API'sini: trace'ler, span'ler, loglar, metrikler, puanlar, analiz. |
write | --write-key | Puanlar, geri bildirimler, veri kümeleri, deneyler, onaylar ve bir çalıştırmanın veri kümesine alınması. |
admin | --admin-key | Bir trace'i silmeyi, denetim günlüğünü okumayı ve aşağıdaki iki kapsamın açtığı her şeyi. |
execute | --execute-key | Bir çalıştırmayı başlatmayı, iptal etmeyi, ona sinyal göndermeyi ve olay yayımlamayı. |
worker | --worker-key | Tanım kaydetmeyi, adım almayı ve sonucunu bildirmeyi. Hiçbir trace okumaz. |
En çok önem taşıyan ayrım ingest ile geri kalan her şey
arasındakidir. Alım anahtarı, span üreten her süreçte bulunur; yazmadığınız
kodu çalıştıranlarda bile. Bu kalabalığa, saklanmış her prompt'u da geri
okuyabilen bir kimlik bilgisi vermek, mcpd'nin kolaylaştırmadığı bir hatadır:
sorgu API'sine sunulan bir alım anahtarı reddedilir.
write, aynı nedenle daha küçük ölçekte ingest'ten
ayrıdır. Bir çalıştırmayı veri kümesine almak, o çalıştırmanın girdisini ve
çıktısını okur; yani yazma kılığına girmiş bir okumadır ve filonuzun taşıdığı
anahtarda yeri yoktur.
admin, read'den ayrıdır çünkü bir çalıştırmayı
silmek onu okumak değildir. --admin-key ayarlanana kadar okuma
anahtarı okuduğu gibi siler de; mcpd bunu açılışta söyler.
execute ile worker, çalıştırma yüzeyinin iki
kapsamıdır. Bir çalıştırmayı başlatmak, birinin worker'ına iş yaptırır ve
para harcatır; bir trace'e not düşmek bunu yapmaz, o yüzden bu
write değildir. Worker anahtarı, adım gövdelerini çalıştıran ve
genellikle sağlayıcı kimlik bilgisini tutan süreçte durur; bu yüzden yalnızca
lease protokolünü açar, saklanmış bir prompt'u okuyan hiçbir şeyi açmaz. İki
seçeneği ayarlayana kadar her ikisi için yazma anahtarları kabul edilir, admin
anahtarı ise her zaman geçerlidir.
Kesinti olmadan yükseltmek
Ayarlanmamış bir --write-key alım anahtarlarını, ayarlanmamış
bir --admin-key ise okuma anahtarlarını kabul eder. Bu iki
kapsam var olmadan önce yapılandırılmış bir kurulum böylece tam olarak sahip
olduğu erişimi korur ve yükseltmede hiçbir şey bozulmaz. Daha dar yetkilere
geçmek için iki seçeneği ayarlayın; hangi durumda olduğunuzu
mcpd config söyler: kapsamın kendi anahtarları varsa
key required, devraldığında ise
key required (ingest keys) veya
key required (read keys) yazar.
Birden çok anahtar için altı seçenekten herhangi birini tekrarlayın; bir
anahtarı kesintisiz döndürmenin yolu budur. Ortam değişkenleri virgülle
ayrılmış bir liste alır. Çağıran, anahtarı
Authorization: Bearer KEY veya X-Mcpd-Key: KEY
olarak sunar; karşılaştırma sabit zamanlıdır, yani ne uzunluk ne de ilk
farkın konumu gözlemlenebilir.
mcpd'nin tanımadığı bir anahtar 401'dir. mcpd'nin tanıdığı ama
kapsamının kapsamadığı bir uçta kullanılan anahtar 403'tür.
İkisini ayrı tutmak önemlidir: 401, gayet doğru olan bir anahtarda yazım
hatası aramaya gönderir.
Hiç anahtar yapılandırılmadığında her kapsam açıktır. Bu bilinçlidir, çünkü ilk çalıştırma bir kimlik bilgisi istememelidir; açılış uyarısının nedeni de budur.
Anahtarların neyi kapsamadığına dikkat edin: bu sürümde
/healthz, /readyz, /metrics ve
arayüzün kendisi anahtarsız sunulur. Sizin için önemliyse bunları kendi
girişinizin arkasına koyun.
Boş bir girdi, listeyi herhangi bir şey okumadan önce atılır. MCPD_EXECUTE_KEYS= ya da bir Kubernetes Secret'ındaki boş bir değer gibi, ayarlanmış ama hiç anahtar içermeyen bir liste servisin başlamasını engeller ve ret iletisi seçeneği ve değişkeni adlandırır; kapsamı ayarlanmamış bırakmak için değişkeni hiç koymayın; boş bir anahtar başlığı gönderen bir istek hiç anahtar sunmamış sayılır. deploy/ içindeki örnek dosyalardan kalan bir yer tutucu, yani büyük ya da küçük harfle REPLACE_WITH veya replace-me ile başlayan her değer, servisin başlamasını engeller; ret iletisi değeri asla değil, seçeneği ya da proje listesini adlandırır. Aynısı --redact-key için de geçerlidir. Her anahtarı openssl rand -hex 32 ile üretin. --write-key, --execute-key ve --worker-key ayarlanmamışsa alım anahtarları çalıştırma da başlatır ve adım da üstlenir; mcpd bunu başlarken ve mcpd doctor içinde uyarır.
Denetim günlüğü
Yük geri veren işleyiciler kimin neyi okuduğunu kaydeder:
GET /v1/api/traces/{id}, span ve log aramaları, geri
bildirim, veri kümesi öğeleri, alma ve silme. Her satır zamanı, işlemi yapan
anahtarın kısa bir özetini, eylemi, projeyi, kaynağı ve yetkilendirmenin izin
verip vermediğini taşır. Anahtarın kendisi hiçbir zaman yazılmaz.
Günlüğü GET /v1/api/audit ile okuyun; admin kapsamı ister.
--retention-days ile budanmaz: kendini, anlattığı verinin
takvimiyle silen bir günlük, artık ortada olmayan veriyi kimin okuduğunu
söyleyemezdi. Bir satırın yazılması, anlattığı okumayı hiçbir zaman
başarısız kılmaz; yazılamayan satır loglanır ve /metrics
üzerinde mcpd_audit_write_failures_total olarak sayılır, ki bu
bir uyarıya değer.
--sample
0.0 ile 1.0 arasında bir kesir. Bu aralığın dışındaki bir değer sessizce
kırpılmaz, açılışta hata verir: --sample must be between 0.0 and 1.0,
got 2.
Karar, trace kimliğinin özeti alınarak verilir; böylece bir yük dengeleyici arkasındaki mcpd örnekleri birbirleriyle konuşmadan aynı trace'leri tutar ve aynılarını atar. Karar her trace için bir kez verilir ve yığındaki o trace'in her span'i tarafından devralınır, çünkü yarım kaydedilmiş bir trace, gözlediğiniz sistemde bir hata gibi görünür.
Özet, trace kimliğinin son baytlarını okur. Bazı üreticiler baştaki baytları bir zaman damgasından türetir; bunlara bakan bir örnekleyici günün saatiyle ilişkilenir ve sessizce koca saatleri düşürürdü.
Politika türü ayrıca "hataları her zaman tut" ve "şundan yavaş olanları her zaman tut" seçeneklerini taşır, ancak bunlar bir trace bittikten sonra verilen kuyruk kararına uygulanır. Bu sürüm yalnızca başta örnekler ve kuyruk örneklemesini açan bir seçenek yoktur. Örnekleme bu ödünleşimi anlatır.
--no-redact, --redact-key, --redact-key-contains ve --redact-max-string
Maskeleme varsayılan olarak açıktır ve her şey yazılmadan önce çalışır; böylece hiç kalıcı olmaması gereken bir değer hiç kalıcı olmaz. Sonradan silmek aynı güvence değildir. Anahtar adının küçük harfli parçalarıyla eşleşen üç kural kümesi yerleşik gelir:
| Kural | Anahtar şunu içerdiğinde uygulanır | Ne saklanır |
|---|---|---|
| Tam | api_key, apikey, api-key,
secret, password, passwd,
access_token, refresh_token,
id_token, bearer,
authorization, auth_token,
private_key, client_secret,
session_token, credential,
signature, x-api-key | [redacted] |
| Kısmi | email, phone, ssn,
credit_card, card_number,
iban |
İlk iki ve son iki karakter, ab…yz. Altı karakter veya
daha kısa bir değer, çoğunu sızdırmak yerine tamamen maskelenir
|
| Özet | user_id, userid | sha256: ve anahtarlı bir özetin 12 baytı; böylece bir
kullanıcıyı saklamadan yine de kullanıcıya göre gruplayabilirsiniz
|
Nesne veya dizi tutan eşleşmiş bir anahtarın altındaki her şey de maskelenir,
böylece {"credentials": {"token": "..."}}
yalnızca iç içe addan yararlanıp sıyrılamaz. 128 KiB'den uzun herhangi bir
tek dize, bayt sayısını bildiren bir işaretle kısaltılır; bu da kaçak bir
prompt'un diskinize yapabileceğini sınırlar.
--redact-key, özetleme kuralının anahtarıdır. Eşit girdiler tek
bir anahtar altında eşit özet verir, gruplamayı çalıştıran budur; anahtarı
döndürmek bu bağı bilerek koparır. Özet alan her kurulumda ayarlayın:
yerleşik varsayılan kaynak kodda durur, yani anahtarsız özetler tahmin
edilebilir.
--redact-key-contains, yerleşik üç kuralın üzerine kendi maskeleme
kuralınızı ekler. Yerleşik kurallar kimlik bilgilerinin genelde hangi adlarla
saklandığını bilir; kendi araçlarınızın müşteri hesap numarasını koyduğu
alanı bilmez. Değer, yerleşik kurallarla aynı şekilde, anahtarın küçük harfli
bir parçası olarak eşleştirilir; yani
--redact-key-contains ticket hem ticket_id hem de
supportTicket alanlarını, eşleşen anahtarın altındaki her şeyle
birlikte maskeler. Birden çoğu için seçeneği tekrarlayın veya
MCPD_REDACT_KEY_CONTAINS değişkenine virgülle ayrılmış bir liste
verin.
--redact-max-string, uzunluk sınırını yerleşik 128 KiB
değerinden aşağı çeker. Sınırdan uzun bir dize, kaç baytın atıldığını
bildiren bir işaretle, saklanmadan önce orada kesilir.
--no-redact, uzunluk sınırı dâhil tüm hattı kapatır. Ortam
değişkeni olarak MCPD_NO_REDACT=true yazılır. Yalnızca yukarı
akışta bir şey zaten maskeleme yapıyorsa mantıklıdır ve yukarıdaki iki ekten
biri yanında ayarlanmışsa daemon başlamayı reddeder, çünkü uygulanacakları
bir şey kalmaz.
--runs-data
Çalıştırma deposunun yeri: tanımlar, adım denemelerinin günlüğü, her son
tarih ve her bekleme. Sinyal deposu ne olursa olsun bu gömülü bir dosyadır;
yani Postgres veya ClickHouse üzerinde bile çalıştırmalar daemon'un yanında
tek bir dosyada durur ve çalıştırma yüzeyini tek bir kopya sunar. Varsayılan
olarak --data yolunun uzantısından önce .runs
eklenmiş hâlidir, varsayılan için ./mcpd.runs.db, ve
--data öyleyse :memory: olur.
--runs-data off hiç çalıştırma sunmaz: her çalıştırma ucu bu
seçeneği adıyla anan bir 503 döndürür ve daemon'un geri kalanı
değişmez.
Deponun zamanlamaları yapılandırma dosyasında runs altında, tam
milisaniye olarak durur: lease_ttl_ms,
reclaim_window_ms, stall_window_ms,
idempotency_window_ms, park_ttl_ms ve
max_depth. Varsayılanlar, 30 saniyelik lease ve 30 saniyelik
geri alma penceresi, tek makinede tek daemon için doğrudur ve bir worker
kaydolduğunda geri okuduğu değerlerdir.
--cors-origin
Sorgu API'sini başka bir siteden hangi tarayıcı kökenlerinin çağırabileceği.
Hiçbiri ayarlanmadığında kökenler arası bir istek
access-control-allow-origin başlığı almaz ve tarayıcı yanıtı
sayfaya vermeyi reddeder. Varsayılan budur ve dizüstünüzdeki, okuma API'si
açık bir daemon'un aynı tarayıcıda açık herhangi bir web sayfası tarafından
okunmasını engelleyen de budur. Birlikte gelen arayüz daemon'un kendi
kökeninden sunulur ve bu seçeneğe hiç ihtiyaç duymaz.
Arayüzü başka bir yerden, bir CDN'den veya bir iç portaldan sunmak, bu
seçeneğin var olma nedenidir: o kökeni şema ve sunucu adı olarak yazın,
örneğin --cors-origin https://console.example. Birden çoğu için
tekrarlayın veya MCPD_CORS_ORIGINS değişkenine virgülle ayrılmış
bir liste verin. Köken olmayan bir değer, console.example ya da
sonunda eğik çizgi olan biri, başlangıcı seçeneği adıyla anarak reddeder. Bu,
sizi bağlanamayan bir arayüzle ve nedenini bilmediğiniz bir sorunla baş başa
bırakmaktan iyidir. --cors-origin '*' her kökene izin verir, ki
daha eski sürümler bunu sormadan yapıyordu.
/healthz, /readyz ve /metrics bu
seçenekle yönetilmez. Saklanmış veri taşımazlar ve arayüz her şeyden önce
/healthz yoklaması yapar, bu yüzden her kökenden okunabilir
kalırlar.
--request-timeout-seconds
Daemon yanıt vermeden önce bir isteğin, gövdenin okunması dâhil,
sürebileceği en uzun süre. Bu süreyi aşan bir işleyiciye, gövdesinde
timeout ve bu seçeneğin adı bulunan bir 503 ile
yanıt verilir. Varsayılan 30 saniyedir; büyük bir yığının okunup saklanmasına
yetecek kadar uzun, bağlantı kabul edip hiç yanıt vermeyen bir depolama arka
ucunun beklenmek yerine bildirilmesini sağlayacak kadar kısadır.
Kapatılamaz; bir işlem gerçekten daha uzun süre gerektiriyorsa yükseltin.
--max-body-bytes ve --max-batch-signals
Tek bir isteğin iki sınırı. --max-body-bytes, daemon'un okuduğu
en büyük gövdedir, varsayılan olarak 32 MiB, ve hiçbiri henüz çözülmeden bir
isteğin ne kadar bellek alabileceğini belirleyen odur. Daha büyük bir gövde,
iki sayıyı da anan bir 413 ile reddedilir; sıkıştırılmış bir
gövde ise açıldıktan sonra aynı rakama tutulur, yani bin katına genişleyen
bir gövde genişletilmek yerine reddedilir.
--max-batch-signals, çözüldükten sonra bir isteğin taşıyabileceği
sinyal sayısıdır, varsayılan olarak 10.000. İsteğin tamamı boyunca sayılır,
yani yığınlardan oluşan bir dizi ve bir NDJSON akışı, tek bir yığınla aynı
sayıya tutulur. Sınırı aşan bir istekte hiçbir şey saklanmaz: ret, ilk
yazmadan sonra değil, öncesinde gelir.
İkisi aynı zamanda yapılandırma dosyası anahtarıdır,
max_body_bytes ve max_batch_signals, ve ikisi de
ayarlıysa seçenek kazanır. Hiçbiri kapatılamaz ve sıfır, "sınır yok" diye
okunmak yerine açılışta reddedilir: sıfırlık bir gövde sınırı her isteği
reddeder, yani cömert görünen okuma alımı düşüren okumadır.
--log-format ve MCPD_LOG
Terminal için text, log hattı için json.
MCPD_LOG bir tracing filtre dizesi alır ve bir
seçeneği yoktur, çünkü bir kurulum kararı değil bir hata ayıklama denetimidir.
İstek başına ayrıntı görmek istediğinizde
mcpd_server=debug olarak ayarlayın.
İki istek sınırı nerede geçerlidir
Gövde sınırı, sorgu API'si dâhil gövde okuyan her yol için geçerlidir. Sinyal sınırı alım kapıları için geçerlidir ve her birinde saydığı şudur.
| Kapı | Sinyal sınırının saydığı |
|---|---|
POST /v1/ingest | İstekteki her span, log, metrik, puan, geri bildirim parçası ve yön notu; tek bir yığın olarak da, yığınlardan oluşan bir dizi olarak da, NDJSON satırlarından oluşan bir akış olarak da gelmiş olsa hepsi toplanarak |
POST /v1/traces | Gönderenin gönderdiği span'ler, eşlenmeden önce sayılır; gönderenin üzerinde işlem yapabileceği sayı budur |
POST /v1/logs | Aktarımdaki log kayıtları |
POST /v1/metrics | Aktarımdaki veri noktaları, içindeki her metrik boyunca |
Alt komutlar
| Komut | Ne yapar |
|---|---|
mcpd serve | Daemon'u çalıştırır. Hiç alt komut verilmediğinde olan da budur |
mcpd demo | Depoya gerçekçi bir örnek çalıştırma yazar, sonra sunar; böylece arayüzü ilk açtığınızda içinde bir şey olur |
mcpd config | Bu çağrının kullanacağı yapılandırmayı yazdırır ve çıkar |
mcpd mcp | Model Context Protocol'ü stdio üzerinden sunar; böylece bir ajan çalışan bir daemon'dan kendi trace'lerini okuyabilir |
mcpd doctor | Bu kurulumu notlandırır ve neyin yanlış yapılandırıldığını bildirir. Bir kusurda 2 koduyla çıkar, yani bir dağıtımı durdurabilir. Bakınız İşletme |
mcpd config, birazdan bir konteynerle yaşayacağınız tartışma
için vardır. Seçenekler, ortam değişkenleri ve varsayılanlar hep tek bir
yerde toplanır; bu komut da sunucu başlatmadan ve veri dosyasına dokunmadan o
yeri yazdırır:
$ MCPD_INGEST_KEYS=k1,k2 mcpd --retention-days 30 --sample 0.1 configlisten 0.0.0.0:4317storage sqlite at ./mcpd.dbconfig file nonelog format textproject defaultprojects noneretention 30 daysingest auth key requiredread auth openwrite auth key required (ingest keys)admin auth openexecute auth key required (ingest keys)worker auth key required (ingest keys)runs sqlite at ./mcpd.runs.dbrun settings lease_ttl_ms 30000, reclaim_window_ms 30000, stall_window_ms 300000, idempotency_window_ms 86400000, park_ttl_ms 86400000, max_depth 8, max_step_repeats 16identity offsampling deterministic 0.1quota unlimitedredaction onredact key built in, which is public; set --redact-keycors same-origin onlytimeout 30s per requestlimits 32 MiB per request, 10000 signals per batchderived duration and token metricsaspects offmonitors noneobjectives nonejudge offforwarding off
Bir şey dağıtmadan önce altı yetki satırını okuyun. open, porta
erişebilen herkese açık demektir. Köşeli parantez içindeki bir satır, o
kapsamın devraldığı daha geniş listeyi adlandırır; eski bir sürümden
yükseltilen bir kurulumun başladığı durum budur.
Yapılandırılmış bir kurulum
Buradaki hiçbir şey mcpd'ye özgü değildir: değişkenler sıradan ortam değişkenleridir, yani Compose'da, bir Kubernetes bildiriminde ve bir systemd biriminde aynı şekilde çalışırlar.
compose
services:
mcpd:
image: ghcr.io/mcpd/mcpd
ports: ['4317:4317']
volumes: ['mcpd-data:/data']
environment:
MCPD_LISTEN: 0.0.0.0:4317
MCPD_DATA: /data/mcpd.db
MCPD_PROJECT: checkout
MCPD_RETENTION_DAYS: '30'
MCPD_INGEST_KEYS: write-key-one,write-key-two
MCPD_READ_KEYS: read-key
MCPD_REDACT_KEY: a-long-random-string
MCPD_LOG_FORMAT: json
MCPD_LOG: mcpd=info,mcpd_server=warn
volumes:
mcpd-data: Bir kabuk veya bir birim dosyası için aynı ayarlar, seçenek olarak:
mcpd --listen 0.0.0.0:4317 --data /data/mcpd.db --retention-days 30 --ingest-key $KEY --log-format json SDK'ların okuduğu değişkenler
Bu değişkenleri daemon değil, ajanınızın süreci okur. Burada listelenmelerinin nedeni iki kümenin ad paylaşması ve hem bir ajan hem de mcpd çalıştıran bir konteynerin tek bir ortamla yapılandırılmasıdır.
| Değişken | Varsayılan |
|---|---|
MCPD_ENDPOINT | http://localhost:4317 |
MCPD_API_KEY | ayarsız |
MCPD_PROJECT | default |
MCPD_ENVIRONMENT | ayarsız |
MCPD_SERVICE_NAME | ayarsız |
MCPD_SERVICE_VERSION | ayarsız |
MCPD_SAMPLE | 1.0 |
MCPD_ENABLED | true |
MCPD_CAPTURE_PAYLOADS | true |
MCPD_LOG_LEVEL | debug |
MCPD_PROJECT ve MCPD_SAMPLE iki tarafta da aynı
anlama gelir, ki genelde istediğiniz budur: bir kez ayarlayın, ajan ve daemon
proje üzerinde anlaşsın. Üzerinde düşünülmesi gereken örneklemedir. SDK bir
trace'i gönderilmeden önce atar, bu da ağı korur. Daemon onu saklanmadan önce
atar, ki oranın denetlemediğiniz gönderenlere uygulanabileceği tek yer
burasıdır. Oranı iki yerde değil tek yerde ayarlayın, yoksa zaten süzülmüş bir
akışı süzüyorsunuz demektir.
MCPD_ENABLED=false, her SDK çağrısını geçerli nesneler döndürmeyi
sürdüren bir boş işleme çevirir; böylece mcpd, hiç kod değiştirmeden
testlerde kapatılabilir. MCPD_CAPTURE_PAYLOADS=false, prompt'ları
ve tamamlamaları süreç içinde tutar: span'ler yine de zamanlamaları,
kullanımları, modelleri ve hatalarıyla gelir, ancak input ve
output kuyruğa alınmadan önce atılır, yani hiç ağdan geçmez.
Daemon üzerindeki maskeleme aynı telin öbür ucudur ve baytları hiç göndermemesi
gereken bir ekip için yanlış uçtur. Dile göre ayrıntı her
SDK sayfasındadır.
--config-file
Komut satırına sığmayan ayarları tutan bir JSON dosyası: izleyiciler, hizmet düzeyi hedefleri, değerlendirildikleri aralık, iletme, yargıç, çalıştırma deposunun zamanlamaları, iki istek sınırı ve aşağıdaki proje bazlı blok. YAML veya TOML yerine JSON, çünkü mcpd zaten diğer her şey için JSON çözümlüyor; yani dosya ne yeni bir bağımlılık ne de öğrenilecek ikinci bir sözdizimi getiriyor. Bir Kubernetes ConfigMap olarak olduğu gibi bağlanır.
max_body_bytes ve max_batch_signals komut satırının
yanı sıra burada da bulunur, böylece bir filo bunları birlikte dağıtıldıkları
izleyicilerin yanında tutabilir. Seçenek dosyayı yener; tek bir örneğin, ortak
dosya herkes için düzenlenmeden farklı bir sınır almasının yolu budur.
Bilinmeyen bir anahtar yok sayılmak yerine başlangıcı düşürür, çünkü sessizce hiçbir şeyi izlemeyen bir yazım hatası mevcut en kötü sonuçtur.
Arka plandaki bir zamanlayıcının çalışamayacağı bir değer de başlangıcı
düşürür: 0 dahil ile 1 hariç arasında olmayan bir objective, 1
ile 365 dışında bir hedef window_days değeri, 86400'ü aşan
monitor_interval_seconds, 1 ile 31536000 dışında bir
aspects.window_seconds, 604800'ü aşan
aspects.interval_seconds ve 1 ile 300 dışında bir
judge.timeout_seconds. Her ret, anahtarı ve aralığı söyler.
{
"max_body_bytes": 33554432,
"max_batch_signals": 10000,
"monitor_interval_seconds": 60,
"monitors": [
{
"id": "error-rate",
"name": "Error rate above 5%",
"project": "checkout",
"watch": "error_rate",
"compare": "above",
"threshold": 0.05,
"window_seconds": 300,
"min_samples": 20,
"webhook": "https://hooks.example.com/mcpd"
}
],
"forward": {
"endpoint": "https://otlp.example.com",
"headers": [["Authorization", "Bearer sk-..."]],
"batch_size": 256,
"enabled": true
}
} Projeler ve onlara erişen anahtarlar
Proje kiracılık anahtarıdır. Bunu süs olmaktan çıkarıp gerçek kılan, anahtarları bir projenin altında listelemektir: bir projenin bloğundaki anahtar o projeye erişir, başkasına erişmez; böylece tek bir daemon, hiçbiri diğerlerinin prompt'larını okuyamadan birkaç ekibe hizmet eder.
{
"projects": {
"checkout": {
"ingest_keys": ["ck-write-..."],
"read_keys": ["ck-read-..."],
"admin_keys": ["ck-admin-..."],
"retention_days": 30,
"sample": 0.25
},
"support": {
"ingest_keys": ["sp-write-..."],
"read_keys": ["sp-read-..."],
"retention_days": 90
}
}
}
Altı listenin altısı da proje başına vardır: ingest_keys,
read_keys, write_keys, admin_keys,
execute_keys ve worker_keys;
ve aynı şekilde geri düşerler: write_keys olmayan bir proje kendi
alım anahtarlarını, admin_keys olmayan bir proje kendi okuma
anahtarlarını kabul eder. Yukarıdaki support bloğu ikisini de
ayarlamıyor, yani tam olarak bu iki kapsam var olmadan önceki gibi davranır.
Altı üst düzey seçenekten herhangi biriyle ayarlanan bir anahtar her projeye erişir. Tek kiracılı yol budur ve basit olan yol olarak kalır: bu bloğu hiç açmazsanız hiçbiriyle karşılaşmazsınız.
retention_days ve sample, bir proje bunları
ayarlamadığında genel seçeneklere geri düşer. İkisi de anahtarlarla aynı
nedenle proje bazlıdır: bir ekibin doksan günlük gereksinimi herkesin
verisinin saklanmasını zorunlu kılmamalı ve bir ekibin trafiği başka bir
ekibin nasıl örnekleneceğine karar vermemelidir.
Bir yığın birkaç projeyi adlandırabilir. Kapsamlı bir alım anahtarı, eriştiklerini yazar, geri kalanını reddeder ve reddi sessizce düşürmek yerine yanıtta bildirir; böylece yanlış projeye yönlendirilmiş bir filo, zaten okumakta olduğu yanıttan görülebilir.
Anahtarınızın erişmediği bir proje için gelen okuma isteği, o projenin var olup olmadığı söylenmeden reddedilir. Paylaşılan bir daemon'da proje adları çoğu zaman ekiplerin veya müşterilerin adlarıdır.
İzleyiciler ve hizmet düzeyi hedefleri
İzleyiciler ve uyarılar
sayfasında ele alınır; hedefler monitors yanındaki bir
slos dizisine girer ve aynı zamanlayıcıyla değerlendirilir.
judge bloğu bir modelin notlandırdığı puanlamayı açar ve
Regresyon testi
sayfasında anlatılır. Siz ayarlayana kadar kapalıdır ve bir istek adını
anmadıkça yargıç kullanan bir puanlayıcı hiç çalışmaz, çünkü notlandırma
okuduğu her çalıştırmada para harcar.
{
"judge": {
"endpoint": "http://localhost:11434/v1",
"model": "qwen2.5:14b",
"api_key": "",
"criteria": {
"answer_relevance": "Does the answer address the question that was asked?"
}
}
} monitor_interval_seconds, izleyicilerin ve hedeflerin ne sıklıkla değerlendirildiğidir. Varsayılanı 60’tır ve 5’in altındaki bir değer 5’e yükseltilir.
derived_metrics
Servisin sakladığı span’lerden türettiği metrikler. Blok yoksa iki yarı da açıktır. durations, biten her ajan, araç, iş akışı, model üretimi ya da işlemci span’i için bir süre noktası yazar. tokens, kullanımını bildiren her model üretimi span’i için on üçe kadar token sayacı yazar. Birini yazmayı durdurmak için false yapın; yazılmayan bir alan açık kalır. Bunun için bir seçenek yoktur. Türetilen noktalar proje başına tavandan sonra eklenir ve bir alım yanıtının bildirdiği accepted sayısına girmez.
{
"derived_metrics": { "durations": true, "tokens": false }
} aspects
Servisin yön notlarını temalara kümeleyip kümelemediği ve hangi sınırlar içinde yaptığı. Blok yoksa kapalıdır. enabled geçişi açar ve model ya da kimlik bilgisi gerektirmez, çünkü outcome yönünü servis kendisi yazar. interval_seconds bir geçişin ne sıklıkla çalıştığıdır, varsayılanı 300’dür ve 30’un altındaki bir değer 30’a yükseltilir. window_seconds bir geçişin notları ne kadar geriye kadar okuduğudur, varsayılanı 86400’dür. disabled hiçbir geçişin kümelemediği görünüşleri adlandırır; bunlardan biri altında kaydedilmiş notlar okunabilir kalır.
{
"aspects": {
"enabled": true,
"interval_seconds": 300,
"window_seconds": 86400,
"disabled": ["sentiment"]
}
} --forward-endpoint
Saklanan her span'i başka bir OTLP/HTTP ucuna kopyalar. Temel URL'yi verin;
sonuna /v1/traces eklenir. Yerel yazma her zaman önce olur, yani
çalışmayan bir hedef size hiçbir şeye mal olmaz.
Bu seçenek, yapılandırma dosyasındaki forward bloğunu yener;
böylece tek bir örnek, ortak bir ConfigMap düzenlenmeden başka bir yere
yönlendirilebilir. Bakınız
İletme.
--forward-header
İletilen her yığınla gönderilen bir başlık, Name: value biçiminde
yazılır. Birden fazlası için seçeneği tekrarlayın. Ortam değişkeni virgülle
ayrılmış bir liste alır.
İki nokta içermeyen bir değer atılmaz; çalışan biçim gösterilerek
başlangıçta reddedilir. OpenTelemetry tarzı bir key=value
başlığı burada key: value olarak yazılır.
--clickhouse-url
Bir ClickHouse sunucusunun HTTP ucu, örneğin
http://clickhouse:8123. Ayarlamak depoyu gömülü dosyadan
ClickHouse'a geçirir ve --data artık okunmaz. Şema açılışta
oluşturulur.
Gömülü depodaki tek yazıcı ve tek kopya sınırlarını kaldıran ayar budur. Saklama süresi aylarca üretim trafiğiyle ölçüldüğünde ona uzanın, daha önce değil: İşletme bu ödünleşimi anlatır.
--clickhouse-database, --clickhouse-user, --clickhouse-password
Tabloların oluşturulacağı veritabanı ve ona erişilecek kimlik bilgileri. Parolası olmayan bir kullanıcı parolasız gönderilir; bu, özel bir ağdaki bir konteyner için doğru, başka her yerde yanlıştır.
--postgres-url
Bir Postgres bağlantı dizesi, örneğin
postgres://mcpd:secret@db:5432/mcpd. Ayarlamak depoyu gömülü
dosyadan Postgres'e geçirir ve --data artık okunmaz. Şema
açılışta oluşturulur.
Bu orta seçenektir. ClickHouse'un kaldırdığı tek yazıcı ve tek kopya
sınırlarını, sizden zaten sahip olmadığınız bir veritabanını çalıştırmanızı
istemeden kaldırır. Hem bunu hem --clickhouse-url adlandırmak,
birini seçmek yerine başlangıcı düşürür.
Göç bir danışma kilidi alır, yani birkaç kopyanın birlikte başlaması güvenlidir; uygulanacak bir şey olmadan yapılan bir başlangıç ise şemaya hiç dokunmaz.
TLS için bağlantı dizesine sslmode=require ekleyin. mcpd
bağlantıyı şifreler ve sunucunun sertifikasını her zaman doğrular. Sertifikayı
genel sertifika yetkililerine göre, ya da sslrootcert=/yol/ca.pem
verilirse o dosyadaki yetkiliye göre denetler; kendi yetkilisi olan yönetilen
bir hizmet bunu gerektirir. verify-ca ve
verify-full, require olarak okunur. Varsayılan
prefer ya da disable ile bağlantı şifrelenmez.
Yalnızca hangi anahtarı değil, kimi kaydetmek
Denetim günlüğü, işlemi yapan anahtarın bir özetini kaydeder. Bu, "bir admin anahtarı bu çalıştırmayı sildi" sorusunu yanıtlar, "hangi kişi sildi" sorusunu değil. mcpd'nin bir kimlik sağlayıcısı yoktur; bu yüzden kimlik, zaten önünde duran girişten gelmelidir.
Vekil sunucunuzun ayarladığı başlığı ve onu ayarlamasına izin verilen adresleri verin:
kimliği güvendiğiniz bir girişten alın
mcpd serve \
--trusted-identity-header x-forwarded-user \
--trusted-proxy-cidr 10.42.0.0/16 İkisi de zorunludur ve bunu güvenli kılan adres listesidir. Başlık, porta soket açabilen herkesin gönderebileceği bir dizedir; bu yüzden mcpd onu yalnızca adını verdiğiniz bir adresten okur. Başka bir yerden gelen istek normal şekilde karşılanır ve denetim satırı hiçbir özne taşımaz, ki tahmin yürütmek yerine dürüst yanıt budur. Değerin uzunluğu da sınırlanır ve denetim karakterlerinden arındırılır, çünkü proxy öyle olmasa da bir başlık saldırganın etkisindedir.
İki seçenek de ayarlanmadığında hiçbir şey değişmez ve hiçbir özne kaydedilmez. Varsayılan budur.
Tek bir proje daemon'un tamamını harcayamaz
mcpd'yi boğan bir proje, üzerindeki diğer her projeye mal olur: disk dolar,
saklama yetişemez ve çalıştırmalarını kaybeden, yanlış bir şey yapmamış olan
ekip olur. --quota-per-minute bunu durduran tavandır.
her proje için bir tavan, birine daha büyüğü
mcpd serve --quota-per-minute 10000
Ayarsız olması tavan yok demektir, yani hiç ayarlamayan bir kurulum tam
olarak kotalar var olmadan önceki gibi davranır. Ayarlandığında üç şeyi
kapsar: projects bloğunda kendi
quota_per_minute değerini vermeyen her projeyi,
--project ile adlandırılan projeyi ve
yapılandırmanın hiç listelemediği her projeyi.
Bunu bir öneri değil bir tavan yapan, sonuncusudur. Proje adı istek gövdesinin içinde gelir; yani hiçbir yapılandırma dosyasının listelemediği bir ad seçen gönderen eskiden hiçbir hesaba yazılmıyor ve sınırsızca saklayabiliyordu. Gönderenin bir dize uydurarak çıkabildiği sınır, sınır değildir.
Listelenmemiş her proje, her birine bir tane verilmesi yerine tek bir sayacı
paylaşır. Ad başına bir sayaç, herhangi bir gönderenin ad uydurarak
sürebileceği bir tahsis olurdu; aynı deliğin başka bir biçimi. Paylaşmak, bin
uydurma ada yayılmış bir taşkının toplamda bu sayıyla sınırlı kalması
demektir; ve kendi payını hak eden bir projenin, payı olan
projects içinde adlandırılması gerektiği anlamına gelir.
Tavanın gerçekte neyi sınırladığı
Sayaç iki pencereli ağırlıklı türdendir: bu dakikanın sayısı, artı ondan önceki dakikanın, şu an biten pencerenin ne kadarını hâlâ kapsadığıyla ağırlıklandırılmış hâli. Sürekli hızı tavanda tutar ve üstüne bir tavan kadarlık ani yüke izin verir, çünkü dolu bir kuyruğu boşaltan SDK tek bir yığın olarak gelir ve bunu reddedecek bir sayaç sıradan trafiği de reddederdi.
Bu ikisinin, saklanmak yerine söylenmeye değer aritmetik bir sonucu vardır. Bir proje 60 saniyelik bir aralık içinde tavanının kılpayı iki katını saklayabilir: bir pencerenin en sonunda tam bir tavan ve bir sonrakinin en sonunda yine tam bir tavan. Bu, yaklaşıklığın bir yan etkisi değildir. Bir projenin tavanını bir anda ve sonrasında dakikada bir tavan daha harcamasına izin veren her sınırlayıcı, bunu bir sınır üzerinde mümkün kılar; kaldırmanın tek yolu ani yükü reddetmektir.
Pencere bir dakikadır ve yapılandırılamaz. Seçenek birimi kendi adında taşıyor; "dakika başına"nın ne demek olduğunu değiştiren ikinci bir ayar, ilk sayıyı okunamaz kılardı.
Fazlasına ne olur
Tavanı aşan sinyaller reddedilir ve bildirilir, hiçbir zaman sessizce düşürülmez. Yığının tamamı reddedilmez: mcpd sığanı saklar ve sığmayanı size söyler.
- Span'ler trace bütünlüğünde gider. Yarım bir çalıştırmada, ebeveynini kimsenin saklamadığı span'ler olur; bu, eksik bir çalıştırma değil bozuk bir çalıştırma gibi okunur. Kalan yere sığmayacak kadar büyük bir trace atlanır ve bir sonraki denenir, böylece tek bir büyük çalıştırma payın kalanını hiçbir şeye harcamaz.
- Loglar, metrikler, puanlar ve geri bildirimler tek başına durur, yani kalan yeri geliş sırasına göre doldururlar.
- Yalnızca saklanan hesaba yazılır. Budama trace'leri bütün tuttuğu için izin verilenden daha az sinyal saklayabilir ve fark geri verilir. Bu olmasaydı, çalıştırmaları kalan payından büyük olan bir proje hiçbir şey saklamadan payını sıfıra kadar harcardı.
- Aynı istekteki diğer projelere dokunulmaz. Tavanını aşan bir proje, yanında gönderdiği sinyalleri başka bir projeye mal etmez.
Yanıt, sayıyı rejected içinde ve projeyi ile tavanını adlandıran
bir satırı errors içinde taşır. Yapılandırmanın hiç listelemediği
bir proje farklı bir cümle alır, çünkü analytics-v2 projesinin
tavanını aştığını duymak, yanıt projeyi eklemekken sizi var olmayan bir ayarı
aramaya gönderir:
$ curl -sX POST "$MCPD/v1/ingest" -H content-type:application/json -d @batch.json | jq{ "accepted": 5, "rejected": 3, "duplicate": 0, "errors": [ { "signal": "span", "index": 0, "message": "3 signal(s) named project analytics-v2, which no configuration lists. Every unlisted project shares one ceiling of 5 per minute and it was full, so they were not stored. Add analytics-v2 to the `projects` block to give it an allowance of its own, or raise --quota-per-minute." } ]}
Bir ret, mcpd_signals_rejected_total yanında
mcpd_signals_over_quota_total içinde de sayılır; böylece
sınırlanan bir filo, bozuk veri gönderen bir filodan ayırt edilebilir.
Bakınız İşletme.
Ayarlarken bakılacak iki şey
Tavan, sinyal saklayan her kapıyı kapsar: yığın kapıları
/v1/ingest, /v1/traces, /v1/logs ve
/v1/metrics, ve tek kayıtlık kapılar
POST /v1/api/scores ile POST /v1/api/feedback.
İkisi, tavanını aşan bir projeye bilerek farklı yanıt verir. Yığın kapısı
sığanı saklar ve kalanını bir gerekçeyle rejected olarak
bildirir, çünkü bir yığın birkaç projeyi adlandırabilir ve isteğin tamamını
reddetmek tavanı içindeki projeleri cezalandırırdı. Tek kayıtlık kapının
verecek kısmi bir yanıtı yoktur, bu yüzden 429 ile ve o projenin
sayacının başka bir sinyali kabul etmesine kaç saniye kaldığını taşıyan bir
Retry-After başlığıyla reddeder. Sayı sayacın kendisinden gelir,
yani ona uyan bir istemci sabit bir gecikme dolduğunda değil yer açıldığında
geri döner.
Bir yazma kapısı buna yazılmaz: saklanan çalıştırmalar üzerinde puanlayıcı
çalıştıran POST /v1/api/score. Ürettiği puanları doğrudan
depolamaya verir, yani tavanı çoktan harcanmış bir proje için de bir geçiş
diske düşer; ve o satırlar ne
mcpd_signals_over_quota_total ne de
mcpd_signals_unbounded_total tarafından sayılır. Bir filonun
yöneldiği bir kapı değil, kendi açtığınız bir kapıdır; bu yüzden tavanı
diske erişebilen her şeyin değil, gönderenlerin içeri itebileceğinin sınırı
sayın.
--max-batch-signals değerinin, varsayılan olarak 10.000, altında
bir tavan, tek bir geçerli yığının koca bir dakikanın payını aşabileceği ve
gönderen ne kadar iyi davranırsa davransın budanacağı anlamına gelir.
mcpd doctor bunu limits altında notlandırır ve
geçerli olduğu projeleri adlandırır. Ayrıca proje başına bir tavan ayarlanmış
ve yanında üst düzey bir tavan ayarlanmamışsa uyarır; her listelenmemiş
projeyi sınırsız bırakan yapılandırma budur.
mcpd config, sınırlanan projeleri adlarıyla yazdırır; böylece
ayarın neyi kapsadığını çıkarım yapmak yerine geri okuyabilirsiniz. Yalnızca
adlandırılmış tavanları yazdırır, bu yüzden paylaşılanı seçeneğin kendisinden
doğrulayın.