عميل Riemann مميز بالكامل مبني على موثوقية Poolboy وقوة Elixir الرائعة!
Riemannx هو عميل Riemann الذي تم تصميمه في Elixir ، وهو حاليًا العميل الوحيد في Elixir الذي يدعم UDP و TLS (وكذلك TCP). يوجد أيضًا وضع تجميع يمكنك استخدامه يعمل مع أي من وسائل النقل.
يحتوي على خيار مشترك تجريبي يحقق أفضل ما في كل من TCP و UDP - في الوضع المدمج UDP هو النهج المفضل ولكن إذا تجاوز حجم الرسالة مجموعة MAX UDP SET TCP.
كما هو الحال دائمًا ، هناك متطلبات مسبقة مطلوبة قبل استخدام Riemannx ، معظمها واضح (Elixir ، Erlang) ولكن يحتوي على بعض المعلومات التي يتم اختبار الإصدارات عليها ودعمها.
حاليًا يتم دعم جميع إصدارات Erlang ~> 18. ويشمل ذلك 20 ، 20.1 لم يتم اختباره بعد ، لكنني لا أتوقع أي مشاكل كبيرة هناك.
تم اختباره بواسطة ترافيس:
18.019.320.0لقد حاولت ضمان التوافق من 1.3.4 فصاعدًا وسأواصل القيام بذلك عند الاقتضاء. مجموعات تم اختبارها:
18.0 Elixir: 1.3.4 / 1.4.5 / 1.5.119.3 Elixir: 1.3.4 / 1.4.5 / 1.5.120.0 Elixir: 1.4.5 / 1.5.1كما هو الحال غالبًا ، يكون العميل عديم الفائدة إلى حد ما بدون نظيره الخادم - لمزيد من المعلومات حول Riemann ، تفضل بزيارة http://riemann.io.
تم اختبار العميل فقط معركة على: 0.2.11 . من الإصدار 4.0.0 من العميل ، ستحتاج إلى تعيين use_micro إلى خطأ إذا كنت تستخدم إصدارًا من Riemann أقدم من 0.2.13 ولا تضع حقل الوقت بنفسك. يجب أن تعمل مع 0.3.0 ولكن مرة أخرى لم يتم اختبارها سابقًا (أي شخص يريد العمل في اختبارات التكامل التي أقدرها كثيرًا).
يحدث التثبيت تمامًا مثل أي مكتبة Elixir أخرى ، وأضفه إلى ملف المزيج الخاص بك والباقي هو السجل:
def deps do
[ { :riemannx , "~> 4.0" } ]
endتأكد من إضافة Riemannx إلى قائمة التطبيقات في ملف mix.exs أيضًا ، وهذا يضمن بدء تشغيله مع تطبيقك وسيتم تضمينه في إصداراتك (إذا كنت تستخدم مدير إصدار):
applications : [ :logger , :riemannx ] لاستخدام Riemannx ، كل ما عليك فعله هو ملء بعض إدخالات التكوين - بعد ذلك يحدث كل شيء بشكل تلقائي (باستثناء الإرسال الفعلي بالطبع). فيما يلي قائمة شاملة بالخيارات المتاحة:
config :riemannx , [
host: "localhost" , # The riemann server
event_host: "my_app" , # You can override the host name sent to riemann if you want (see: Host Injection)
send_timeout: 30_000 , # Synchronous send timeout
checkout_timeout: 30_000 , # Timeout for checking out a poolboy worker
type: :batch , # The type of connection you want to run (:tcp, :udp, :tls, :combined, :batch)
settings_module: Riemannx.Settings.Default # The backend used for reading settings back
metrics_module: Riemannx . Metrics.Default # The backend used for sending metrics
use_micro: true # Set to false if you use a riemann version before 0.2.13
batch_settings: [
type : :combined # The underlying connection to use when using batching.
size: 50 , # The size of batches to send to riemann.
interval: { 1 , :seconds } , # The interval at which to send batches.
limit: :infinity # The max limit of batches allowed in the batching queue
]
tcp: [
port : 5555 ,
retry_count: 5 , # How many times to re-attempt a TCP connection
retry_interval: 1000 , # Interval to wait before the next TCP connection attempt (milliseconds).
priority: :high , # Priority to give TCP workers.
options: [ ] , # Specify additional options to be passed to gen_tcp (NOTE: [:binary, nodelay: true, packet: 4, active: true] will be added to whatever you type here as they are deemed essential)
pool_size: 5 , # How many TCP workers should be in the pool.
max_overflow: 5 , # Under heavy load how many more TCP workers can be created to meet demand?
strategy: :fifo # The poolboy strategy for retrieving workers from the queue
] ,
udp: [
port: 5555 ,
priority: :high ,
options: [ ] , # Specify additional options to be passed to gen_udp (NOTE: [:binary, sndbuf: max_udp_size()] will be added to whatever you type here as they are deemed essential)
max_size: 16_384 , # Maximum accepted packet size (this is configured in your Riemann server)
pool_size: 5 ,
max_overflow: 5 ,
strategy: :fifo
] ,
tls: [
port: 5554 ,
retry_count: 5 , # How many times to re-attempt a TLS connection
retry_interval: 1000 , # Interval to wait before the next TLS connection attempt (milliseconds).
priority: :high ,
options: [ ] , # Specify additional options to be passed to :ssl (NOTE: [:binary, nodelay: true, packet: 4, active: true] will be added to whatever you type here as they are deemed essential)
pool_size: 5 ,
max_overflow: 5 ,
strategy: :fifo
]
] Riemannx يدعم طريقتين send ، واحدة غير متزامنة أخرى متزامنة:
يتيح لك الإرسال المتزامن التعامل مع الأخطاء التي قد تحدث أثناء الإرسال ، فيما يلي مثال يوضح كيف يبدو هذا الخطأ وما يحدث في إرسال ناجح:
event = [ service: "riemannx-elixir" ,
metric: 1 ,
attributes: [ a: 1 ] ,
description: "test" ]
case Riemannx . send ( event ) do
:ok ->
"Success!"
[ error: error , msg: encoded_msg ] ->
# The error will always be a string so you can output it as it is.
#
# The encoded message is a binary blob but you can use the riemannx proto
# msg module to decode it if you wish to see it in human readable form.
msg = encoded_msg |> Riemannx.Proto.Msg . decode ( )
Logger . warn ( "Error: #{ error } Message: #{ inspect msg } " )
endالإرسال غير المتزامن أسرع بكثير ، لكنك لا تعرف أبدًا ما إذا كانت رسالتك قد صنعت ذلك ، في كثير من الحالات يكون هذا النوع من الإرسال آمنًا بما فيه الكفاية ، وبالنسبة لمعظم حالات الاستخدام ، فإن الخيار الموصى به. من السهل التنفيذ إلى حد ما:
event = [ service: "riemannx-elixir" ,
metric: 1 ,
attributes: [ a: 1 ] ,
description: "test" ]
Riemannx . send_async ( event )
# Who knows if it made it? Who cares? 60% of the time it works everytime!ملاحظة: إذا كان العامل غير قادر على إرساله سيموت ويتم إعادة تشغيله مع إعطاء فرصة للعودة إلى حالة "صحيحة". على إرسال غير متزامن يتم إرسال هذا عن طريق مطابقة الأنماط: حسنًا مع أمر الإرسال ، للمرسلات المتزامنة إذا كانت قيمة الإرجاع خطأ نقتل العامل قبل إرجاع النتيجة.
يتيح لك دعم TLS استخدام اتصال TCP آمن مع خادم Riemann الخاص بك ، لمعرفة المزيد حول كيفية إعداد هذا إلقاء نظرة هنا: Secure Riemann Traffic باستخدام TLS
إذا اخترت استخدام TLS ، فستستخدم إعداد TCP بحت ، غير مدعوم (ولا ينبغي أن يكون أيضًا) مع TLS:
config :riemannx , [
host: "127.0.0.1" ,
type: :tls ,
tls: [
port: 5554 ,
retry_count: 5 , # How many times to re-attempt a TLS connection
retry_interval: 1000 , # Interval to wait before the next TLS connection attempt (milliseconds).
priority: :high ,
# SSL Opts are passed to the underlying ssl erlang interface
# See available options here: http://erlang.org/doc/man/ssl.html
# (NOTE: [:binary, nodelay: true, packet: 4, active: true] will be added to whatever you type here as they are deemed essential)
options: [
keyfile: "path/to/key" ,
certfile: "path/to/cert" ,
verify_peer: true
] ,
pool_size: 5 ,
max_overflow: 5 ,
strategy: :fifo
]
]على افتراض أنك قمت بإعداد جانب الخادم بشكل صحيح ، يجب أن يكون كل ما تحتاجه للبدء.
لدى Riemann مفهوم فهرس Queryable الذي يسمح لك بالبحث عن أحداث محددة ، يجب إنشاء الفهارس خصيصًا في التكوين وإلا فإن الخادم سيعيد خطأ "لا فهرس".
# Lets send an event that we can then query
Riemannx . send ( [ service: "riemannx" , metric: 5.0 , attributes: [ v: "2.2.0" ] ] )
# Let's fish it out
events = Riemannx . query ( 'service ~= "riemannx"' )
# [%{attributes: %{"v" => "2.2.0"}, description: nil, host: _,
# metric: nil, service: "riemannx", state: nil, tags: [],
# time: _, ttl: _}]لمزيد من المعلومات حول الاستعلام وميزات اللغة ، تنظر إلى المفاهيم الأساسية.
يحتوي هذا القسم على بعض الملاحظات حول سلوك Riemannx التي قد تهمك أو تجيب على الأسئلة التي لديك حول أشياء معينة.
يعد التضليل اعتبارًا من 4.0.0 هو سلوك الاتصال الافتراضي - حجم الدفعة الافتراضي هو 50 والفاصل الزمني كل ثانية واحدة. يعمل التجميع مثل ذلك:
كل ما هو في قائمة الانتظار سيتم إرسال كل فاصل.
إذا وصل حجم قائمة الانتظار إلى حجم المجموعة المحددة ، فسيتم مسحه بغض النظر عن الفاصل الزمني.
سيتم إسقاط دفعات إذا لم يكن هناك عمال متاحون للتعامل مع الدُفعة ما لم يتم ضبط checkout_timer على :infinity
هناك نوع جديد يسمى :batch ومفتاح الإعدادات يسمى batch_settings: ، داخل batch_settings ، يمكنك تحديد نوع للاتصال الأساسي ( :tcp ، :udp ، :combined ، :tls ). كما هو الحال دائما مجتمعة هو الافتراضي.
اختياريا ، يمكن تحديد رقم حد الدُفعة ( :limit ). إذا تم تعيينها ، بمجرد أن تحتوي قائمة انتظار الدفع على كمية محددة من الدُفعات ، فهذا هو أحداث limit * batch_size ، سيتم إسقاط أحداث جديدة حتى يتم إرسال دفعة واحدة على الأقل. القيمة الافتراضية هي :infinity
من الإصدار 0.2.13 من Riemann ، كان من الممكن تعيين الوقت في Microseconds - Riemannx يدعم الآن ويستخدم حقل time_micros (ما لم تكن قد حددت الوقت أو حقل الوقت _micros بنفسك ، لن يكتب Riemannx ذلك). إذا كنت تستخدم إصدارًا أقدم من Riemann ، فسيستخدم فقط حقل Seconds.
ملاحظة: إذا قمت بتعيين كل من الوقت والوقت _micros Riemann ، فلن يعط الوقت الأولوية للوقت الدقيق ، وسوف يقوم Riemannx بكتابة فوق.
يبدو الأمر مربيًا أكثر مما يصفه بشكل أساسي الوظيفة التي تضيف إدخال المضيف إلى الحدث الخاص بك إذا لم تحدد واحدة. هناك 3 طرق لتحديد مضيف:
افعل ذلك قبل إرسال الحدث (أضف: مفتاح مضيف إلى قائمة الكلمات الرئيسية)
أضف مفتاح :event_host إلى التكوين الخاص بك.
دع Riemannx تفعل ذلك باستخدام :inet.gethostname() - نحن فقط نسمي ذلك مرة واحدة وحفظ النتيجة ، لا يتم استدعاؤه في كل حدث.
الخيارين الأخيرين هما الأكثر ملاءمة لأنها ستبقي رمزك نظيفًا.
في هذا العميل ، هناك فرصة لوضع أولوية للعاملين في السماح لك بوضع أولوية أعلى أو أقل على إرسال إحصائياتك إلى Riemann.
يعتمد الاختلاف على تحديد الأولوية بشكل كبير على الأجهزة وكيف قمت بتعيين أولوياتك الأخرى بشكل عام ، ويمكن الاطلاع على مزيد من المعلومات هنا: http://erlang.org/doc/man/erlang.html#process_flag-2
إذا حاولت تعيين الأولوية على: سيقوم Max Riemannx برفع وقت تشغيل لأن هذه فكرة فظيعة. كما أنه سيعزز وقت التشغيل إذا حاولت: فو لأن هذه فكرة رهيبة أيضًا.
إن الترحيل إلى 3.0 هو في الأساس مجرد حالة لتغيير تخطيط التكوين الخاص بك - جميع الخيارات نفسها موجودة باستثناء الآن لديك المزيد من التحكم في العاملين في مستوى النوع ، وهذا أمر ذي قيمة خاصة عند استخدام الإعداد المشترك كما يمكنك ، على سبيل المثال ، مجموعة أصغر من عمال TCP ومجموعة أكبر لعامل UDP بدلاً من ذلك (2x مهما كان ما تقدمه).
يمكنك رؤية هذا التصميم الجديد هنا: التكوين
إذا كان أي شيء لا معنى له هنا ، فلا تتردد في فتح مشكلة حتى نتمكن من توسيع نطاق ReadMe لإصلاح الإلغاء.
إذا كنت ترغب في تخزين الإعدادات الخاصة بك في مكان آخر ، يمكنك إنشاء واجهة خلفية لقراءة الإعدادات من قاعدة بيانات على سبيل المثال. انظر إلى وحدة الإعدادات الافتراضية لعمليات الاسترجاعات المطلوبة.
قد يكون هذا مفيدًا إذا كنت ترغب في تخزين إعدادات الشركة في مكان واحد.
لا تتردد في فتح مشكلة إذا كانت لديك أسئلة.
يدعم Riemannx إرسال المقاييس الأساسية ، يمكنك إنشاء وحدة مخصصة لدعم أي بنية تحتية (الجرافيت ، التدفق ، إلخ). هناك 3 عمليات استدعاء حاليًا:
udp_message_sent(size) - يُعلم عند إرسال رسالة UDP وتعطي حجم الرسالة.tcp_message_sent(size) - يُعلم عند إرسال رسالة TCP وتعطي حجم الرسالة.tls_message_sent(size) - يُعلم عند إرسال رسالة TLS وتعطي حجم الرسالة. يتم استلام المساهمات بحرارة ، تحقق من قسم المشاريع للحصول على بعض الأفكار التي كتبتها وللأحدث على ما يجري.
يستخدم هذا المستودع سير عمل gitflow مما يعني أن جميع العلاقات العامة يجب أن تتم توجيهها نحو فرع التطوير! . فيما يلي بعض الأشياء التي يجب مراعاتها قبل إنشاء العلاقات العامة:
أود الحفاظ على تغطية الاختبار بنسبة 100 ٪! - قد أترك هذه الشريحة في الحالات العاجلة (الأخطاء وما إلى ذلك)
لتجنب ازدحام Travis دون داع ، سيكون موضع تقدير إذا قمت بفحص ما يلي أولاً أولاً:
mix coveralls.html (الهدف من 100 ٪)mix dialyzer (يستغرق بعض الوقت وأقدر أنه لا يمكنك اختبار جميع إصدارات إرلانج/إكسير)أنا أعتبر ميزة العميل هذه كاملة ، إذا كانت العلاقات العامة الخاصة بك تعطل توافقك للخلف تمامًا أو يغير السلوك/الافتراضيات الموجود مسبقًا ، فأنا أقدر رؤوسًا وتبريراتك :).
تم استعارة جزء من الكود من عميل Elixir-Riemann الأصلي. معظم الأشياء protobuf تأتي من هناك.