Apache APISIX प्लगइन को 0 से 1 तक कैसे बनाएं?

Qi Guo

Qi Guo

February 16, 2022

Ecosystem

पिछले कुछ महीनों में, समुदाय उपयोगकर्ताओं ने Apache APISIX में कई प्लगइन्स जोड़े हैं, जिससे Apache APISIX इकोसिस्टम को समृद्ध किया गया है। उपयोगकर्ता के दृष्टिकोण से, अधिक विविध प्लगइन्स का उभरना निश्चित रूप से एक अच्छी बात है, क्योंकि वे Apache APISIX की उच्च प्रदर्शन और कम विलंबता को पूर्ण करने के साथ-साथ एक "वन-स्टॉप" और "मल्टी-फंक्शनल" गेटवे की उपयोगकर्ता की अपेक्षाओं को पूरा करते हैं।

Apache APISIX ब्लॉग पर कोई भी लेख प्लगइन्स विकसित करने की प्रक्रिया के बारे में विस्तार से नहीं जाता है। तो आइए एक प्लगइन डेवलपर के दृष्टिकोण से इस प्रक्रिया को देखें और देखें कि एक प्लगइन कैसे जन्म लेता है!

यह लेख एक फ्रंट-एंड इंजीनियर द्वारा जिसे बैक-एंड का कोई अनुभव नहीं है, file-logger प्लगइन विकसित करने की प्रक्रिया को दस्तावेज़ करता है। कार्यान्वयन प्रक्रिया के विवरण में जाने से पहले, हम file-logger की कार्यक्षमता का संक्षिप्त परिचय देंगे।

file-logger प्लगइन का परिचय

file-logger Apache APISIX प्लगइन मेटाडेटा का उपयोग करके कस्टम लॉग फॉर्मेट जनरेट करने का समर्थन करता है। उपयोगकर्ता file-logger प्लगइन के माध्यम से JSON फॉर्मेट में अनुरोध और प्रतिक्रिया डेटा को लॉग फाइलों में जोड़ सकते हैं, या लॉग डेटा स्ट्रीम को एक निर्दिष्ट स्थान पर पुश कर सकते हैं।

इसकी कल्पना करें: जब हम एक रूट के एक्सेस लॉग की निगरानी कर रहे हैं, तो हम न केवल कुछ अनुरोध और प्रतिक्रिया डेटा के मूल्य के बारे में चिंतित हैं, बल्कि लॉग डेटा को एक निर्दिष्ट फाइल में लिखना भी चाहते हैं। यहीं पर file-logger प्लगइन इन लक्ष्यों को प्राप्त करने में मदद कर सकता है।

how it works

हम file-logger का उपयोग करके लॉग डेटा को एक विशिष्ट लॉग फाइल में लिख सकते हैं ताकि निगरानी और डिबगिंग की प्रक्रिया को सरल बनाया जा सके।

एक प्लगइन कैसे लागू करें?

file-logger की विशेषताओं का परिचय देने के बाद, आप इस प्लगइन को बेहतर समझ पाएंगे। निम्नलिखित में, मैं, एक फ्रंट-एंड डेवलपर जिसे सर्वर-साइड का कोई अनुभव नहीं है, Apache APISIX के लिए प्लगइन विकसित करने और इसके लिए संबंधित परीक्षण जोड़ने की प्रक्रिया का विस्तार से वर्णन करूंगा।

प्लगइन का नाम और प्राथमिकता निर्धारित करें

Apache APISIX प्लगइन डेवलपमेंट गाइड खोलें और प्राथमिकता के क्रम में आपको निम्नलिखित दो चीजें निर्धारित करने की आवश्यकता है:

  1. प्लगइन श्रेणी निर्धारित करें।
  2. प्लगइन्स को प्राथमिकता दें और conf/config-default.yaml फाइल को अपडेट करें।

चूंकि file-logger का यह विकास एक लॉगिंग प्रकार का प्लगइन है, इसलिए मैं Apache APISIX के मौजूदा लॉगिंग प्लगइन्स के नाम और क्रम का संदर्भ लेता हूं और file-logger को यहां रखता हूं।

file-logger's position

अन्य प्लगइन लेखकों और समुदाय के उत्साही सदस्यों से परामर्श करने के बाद, प्लगइन का नाम file-logger और प्राथमिकता 399 अंततः निर्धारित की गई।

ध्यान दें कि प्लगइन की प्राथमिकता निष्पादन के क्रम से संबंधित है; प्राथमिकता का मूल्य जितना अधिक होगा, निष्पादन उतना ही आगे होगा। और प्लगइन नामों का क्रम निष्पादन के क्रम से संबंधित नहीं है।

एक न्यूनतम निष्पादन योग्य प्लगइन फाइल बनाएं

प्लगइन नाम और प्राथमिकता की पुष्टि करने के बाद, आप apisix/plugins/ डायरेक्टरी में हमारे प्लगइन कोड फाइल बना सकते हैं। यहां दो बातों का ध्यान रखना है:

  • यदि प्लगइन कोड फाइल सीधे apisix/plugins/ डायरेक्टरी में बनाई जाती है, तो Makefile फाइल को बदलने की आवश्यकता नहीं है।
  • यदि आपके प्लगइन का अपना कोड डायरेक्टरी है, तो आपको Makefile फाइल को अपडेट करने की आवश्यकता है, कृपया Apache APISIX प्लगइन डेवलपमेंट गाइड में विस्तृत चरणों का संदर्भ लें।
  1. यहां हम apisix/plugins/ डायरेक्टरी में file-logger.lua फाइल बनाते हैं।
  2. फिर हम example-plugin के आधार पर एक आरंभिक संस्करण पूरा करेंगे।
-- हेडर में हमें आवश्यक मॉड्यूल को शामिल करें local log_util = require("apisix.utils.log-util") local core = require("apisix.core") local plugin = require("apisix.plugin") local ngx = ngx -- प्लगइन का नाम घोषित करें local plugin_name = "file-logger" -- प्लगइन स्कीमा फॉर्मेट को परिभाषित करें local schema = { type = "object", properties = { path = { type = "string" }, }, required = {"path"} } -- प्लगइन मेटाडेटा स्कीमा local metadata_schema = { type = "object", properties = { log_format = log_util.metadata_schema_log_format } } local _M = { version = 0.1, priority = 399, name = plugin_name, schema = schema, metadata_schema = metadata_schema } -- जांचें कि प्लगइन कॉन्फ़िगरेशन सही है या नहीं function _M.check_schema(conf, schema_type) if schema_type == core.schema.TYPE_METADATA then return core.schema.check(metadata_schema, conf) end return core.schema.check(schema, conf) end -- लॉग चरण function _M.log(conf, ctx) core.log.warn("conf: ", core.json.encode(conf)) core.log.warn("ctx: ", core.json.encode(ctx, true)) end return _M

एक बार न्यूनतम उपलब्ध प्लगइन फाइल तैयार हो जाने के बाद, प्लगइन की कॉन्फ़िगरेशन डेटा और अनुरोध से संबंधित डेटा को core.log.warn(core.json.encode(conf)) और core.log.warn("ctx: ", core.json.encode(ctx, true)) के माध्यम से error.log फाइल में आउटपुट किया जा सकता है।

प्लगइन को सक्षम करें और परीक्षण करें

निम्नलिखित परीक्षण के लिए कुछ चरण हैं। यह परीक्षण करने के लिए कि क्या प्लगइन हमारे द्वारा कॉन्फ़िगर की गई प्लगइन डेटा और अनुरोध से संबंधित डेटा जानकारी को त्रुटि लॉग फाइल में सफलतापूर्वक प्रिंट कर सकता है, हमें प्लगइन को सक्षम करने और एक परीक्षण रूट बनाने की आवश्यकता है।

  1. स्थानीय रूप से एक परीक्षण अपस्ट्रीम तैयार करें (इस लेख में उपयोग किया गया परीक्षण अपस्ट्रीम 127.0.0.1:3030/api/hello है, जिसे मैंने स्थानीय रूप से बनाया है)।

  2. curl कमांड के माध्यम से एक रूट बनाएं और हमारे नए प्लगइन को सक्षम करें।

    curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "plugins": { "file-logger": { "path": "logs/file.log" } }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:3030": 1 } }, "uri": "/api/hello" }'

    फिर आपको एक स्थिति कोड 200 दिखाई देगा, जो इंगित करता है कि रूट सफलतापूर्वक बनाया गया है।

  3. रूट को अनुरोध भेजने के लिए curl कमांड चलाएं ताकि यह परीक्षण किया जा सके कि file-logger प्लगइन शुरू हो गया है या नहीं।

    curl -i http://127.0.0.1:9080/api/hello HTTP/1.1 200 OK ... hello, world
  4. logs/error.log फाइल में एक रिकॉर्ड होगा:

    record in logs/error.log

    जैसा कि आप देख सकते हैं, प्लगइन के लिए हमारे द्वारा कॉन्फ़िगर किया गया path: logs/file.log conf पैरामीटर में सफलतापूर्वक सहेजा गया है। इस बिंदु पर हमने सफलतापूर्वक एक न्यूनतम उपयोग योग्य प्लगइन बनाया है जो लॉगिंग चरण में conf और ctx पैरामीटर्स को प्रिंट करता है।

    इसके बाद, हम file-logger.lua प्लगइन के लिए कोर फंक्शनलिटी को सीधे इसके कोड फाइल में लिख सकते हैं। यहां हम Apache APISIX को पुनः आरंभ किए बिना सीधे apisix reload कमांड चला सकते हैं ताकि नवीनतम प्लगइन कोड को पुनः लोड किया जा सके।

file-logger प्लगइन के लिए कोर फंक्शन लिखें

file-logger प्लगइन का मुख्य कार्य लॉग डेटा लिखना है। समुदाय के अन्य लोगों से पूछने और जानकारी की जांच करने के बाद, मैंने Lua के IO लाइब्रेरी के बारे में जाना, और पुष्टि की कि प्लगइन के फंक्शन की लॉजिक मोटे तौर पर निम्नलिखित चरणों की है।

  1. प्रत्येक स्वीकृत अनुरोध के बाद, लॉग डेटा को प्लगइन द्वारा कॉन्फ़िगर किए गए path में आउटपुट करें।

    1. सबसे पहले, लॉगिंग चरण में conf के माध्यम से file-logger में path का मूल्य प्राप्त करें।
    2. फिर, Lua IO लाइब्रेरी का उपयोग करके फाइल बनाएं, खोलें, लिखें, कैश को रिफ्रेश करें, और फाइल को बंद करें।
  2. फाइल खोलने में विफलता, फाइल बनाने में विफलता जैसी त्रुटियों को संभालें।

    local function write_file_data(conf, log_message) local msg, err = core.json.encode(log_message) if err then return core.log.error("message json serialization failed, error info : ", err) end local file, err = io_open(conf.path, 'a+') if not file then core.log.error("failed to open file: ", conf.path, ", error info: ", err) else local ok, err = file:write(msg, '\n') if not ok then core.log.error("failed to write file: ", conf.path, ", error info: ", err) else file:flush() end file:close() end end
  3. http-logger प्लगइन के स्रोत कोड का संदर्भ लेते हुए, मैंने लॉग डेटा को लॉग डेटा में पास करने की विधि और मेटाडेटा के कुछ निर्णय और प्रसंस्करण को पूरा किया।

    function _M.log(conf, ctx) local metadata = plugin.plugin_metadata(plugin_name) local entry if metadata and metadata.value.log_format and core.table.nkeys(metadata.value.log_format) > 0 then entry = log_util.get_custom_format_log(ctx, metadata.value.log_format) else entry = log_util.get_full_log(ngx, conf) end write_file_data(conf, entry) end

सत्यापन और परीक्षण जोड़ें

लॉग रिकॉर्ड्स का सत्यापन करें

चूंकि परीक्षण रूट बनाते समय file-logger प्लगइन सक्षम किया गया था और पथ को logs/file.log के रूप में कॉन्फ़िगर किया गया था, इसलिए हम परीक्षण रूट को एक अनुरोध भेजकर लॉग संग्रह के परिणामों को सत्यापित कर सकते हैं।

curl -i http://127.0.0.1:9080/api/hello

संबंधित logs/file.log में हम देख सकते हैं कि प्रत्येक रिकॉर्ड JSON फॉर्मेट में सहेजा गया है। डेटा में से एक को फॉर्मेट करने के बाद, यह इस तरह दिखता है।

{ "server": { "hostname": "....", "version": "2.11.0" }, "client_ip": "127.0.0.1", "upstream": "127.0.0.1:3030", "route_id": "1", "start_time": 1641285122961, "latency": 13.999938964844, "response": { "status": 200, "size": 252, "headers": { "server": "APISIX/2.11.0", "content-type": "application/json; charset=utf-8", "date": "Tue, 04 Jan 2022 08:32:02 GMT", "vary": "Accept-Encoding", "content-length": "19", "connection": "close", "etag": "\"13-5j0ZZR0tI549fSRsYxl8c9vAU78\"" } }, "service_id": "", "request": { "querystring": {}, "size": 87, "method": "GET", "headers": { "host": "127.0.0.1:9080", "accept": "*/*", "user-agent": "curl/7.77.0" }, "url": "http://127.0.0.1:9080/api/hello", "uri": "/api/hello" } }

इससे लॉग रिकॉर्ड्स के संग्रह का सत्यापन समाप्त होता है। सत्यापन परिणाम इंगित करते हैं कि प्लगइन सफलतापूर्वक लॉन्च हुआ और उचित डेटा लौटाया।

प्लगइन के लिए अधिक परीक्षण जोड़ें

add_block_preprocessor कोड के हिस्से के लिए, जब मैंने इसे पहली बार लिखना शुरू किया तो मैं भ्रमित था क्योंकि मेरे पास Perl का कोई पूर्व अनुभव नहीं था। शोध करने के बाद, मैंने इसका सही उपयोग करने का तरीका समझा: यदि हम डेटा सेक्शन में request दावों और no_error_log दावों को नहीं लिखते हैं, तो डिफ़ॉल्ट दावा निम्नलिखित है।

--- request GET /t --- no_error_log [error]

कुछ अन्य लॉगिंग टेस्ट फाइल्स को ध्यान में रखते हुए, मैंने t/plugin/ डायरेक्टरी में file-logger.t फाइल बनाई।

प्रत्येक टेस्ट फाइल **DATA** द्वारा एक प्रस्तावना सेक्शन और एक डेटा सेक्शन में विभाजित होती है। चूंकि आधिकारिक वेबसाइट पर टेस्ट से संबंधित दस्तावेज़ों का कोई स्पष्ट वर्गीकरण नहीं है, आप अधिक विवरण के लिए लेख के अंत में संबंधित सामग्री का संदर्भ ले सकते हैं। यहां मैंने संबंधित सामग्री का संदर्भ लेने के बाद पूरा किया गया एक टेस्ट केस है।

use t::APISIX 'no_plan'; no_long_string(); no_root_location(); add_block_preprocessor(sub { my ($block) = @_; if (! $block->request) { $block->set_value("request", "GET /t"); } if (! $block->no_error_log && ! $block->error_log) { $block->set_value("no_error_log", "[error]"); } }); run_tests; __DATA__ === TEST 1: sanity --- config location /t { content_by_lua_block { local configs = { -- full configuration { path = "file.log" }, -- property "path" is required { path = nil } } local plugin = require("apisix.plugins.file-logger") for i = 1, #configs do ok, err = plugin.check_schema(configs[i]) if err then ngx.say(err) else ngx.say("done") end end } } --- response_body_like done property "path" is required

इससे प्लगइन जोड़ने का टेस्ट सत्र समाप्त होता है।

सारांश

उपरोक्त एक नए बैकएंड डेवलपर के रूप में Apache APISIX प्लगइन को 0 से लागू करने की पूरी प्रक्रिया है। प्लगइन विकसित करने की प्रक्रिया में मैंने बहुत सी समस्याओं का सामना किया, लेकिन सौभाग्य से Apache APISIX समुदाय में कई उत्साही भाई हैं जिन्होंने मेरी समस्याओं को हल करने में मदद की, जिससे file-logger प्लगइन का विकास और परीक्षण पूरे समय सुचारू रूप से चला। यदि आप इस प्लगइन में रुचि रखते हैं, या प्लगइन के विवरण देखना चाहते हैं, तो आप आधिकारिक Apache APISIX दस्तावेज़ का संदर्भ ले सकते हैं।

Apache APISIX वर्तमान में अन्य प्लगइन्स पर भी काम कर रहा है ताकि अधिक एकीकरण सेवाओं का समर्थन किया जा सके, इसलिए यदि आप रुचि रखते हैं, तो कृपया GitHub Discussion में चर्चा शुरू करें, या मेलिंग लिस्ट के माध्यम से।

संदर्भ

Tags: