پیکربندی خطای استقرار ناموفق بود

شما در حال مشاهده اسناد Apigee Edge هستید.
مشاهده مستندات Apigee X.

علامت

استقرار پراکسی API یا ویرایش‌های جریان مشترک از طریق رابط کاربری Edge یا مدیریت API با خطای پیکربندی ناموفق انجام می‌شود.

پیغام خطا

مطابق شکل زیر در رابط کاربری Edge پیغام خطا دریافت خواهید کرد:

The revision is deployed, but traffic cannot flow.
com.apigee.kernel.exceptions.spi.UncheckedException{ code = application.bootstrap.FailedToConfigure, message = Configuration failed, associated contexts = []}

در اینجا تصویری از یک پیام خطای نمونه مشاهده شده در Edge UI آمده است:

علل احتمالی

استقرار یک پروکسی API ممکن است با خطای "پیکربندی انجام نشد" به دلایل مختلف شکست بخورد. جدول زیر چند علت مشاهده شده اغلب که منجر به این خطا می شود را فهرست می کند:

علت شرح دستورالعمل های عیب یابی قابل اجرا برای
کلاس جاوا در خط مشی JavaCallout وجود ندارد یک کلاس جاوا از فایل JAR که توسط خط مشی JavaCallout ارجاع شده است وجود ندارد. کاربران ابر خصوصی Edge
عملوندهای نادرست مورد استفاده در شرایط در جریان شرایط عملوندها/عبارات استفاده شده در یک یا هر دو طرف عملگرها در شرایط معتبر نیستند.
نام میزبان در خط مشی ثبت پیام نامعتبر است نام میزبان استفاده شده در خط مشی MessageLogging قابل حل نیست یا ممکن است دارای نویسه های خاص ناخواسته باشد.
نام KeyValueMap نامعتبر است KeyValueMap در خط مشی KeyValueMapOperations در پروکسی API نامعتبر یا خالی است.

مراحل تشخیص رایج

  1. با استفاده از API زیر، وضعیت استقرار را برای ویرایش خاص پروکسی API که خطای استقرار آن را مشاهده می کنید، دریافت کنید:

    curl -v <management-server-host>:<port#>/v1/runtime/organizations/<org-name>/environments/<env-name>/apis/<apiproxy-name>/revisions/deployments -u <user>
    
  2. در اینجا یک نمونه خروجی از API بالا آمده است.

    "server" : [ { 
    "error" : "com.apigee.kernel.exceptions.spi.UncheckedException{ code = application.bootstrap.FailedToConfigure, message = Configuration failed, associated contexts = []}", 
    "status" : "error", 
    "type" : [ "message-processor" ], 
    "uUID" : "0a20926c-f4bf-401b-af84-05fd84b9f492" 
    }, { 
    "error" : "com.apigee.kernel.exceptions.spi.UncheckedException{ code = application.bootstrap.FailedToConfigure, message = Configuration failed, associated contexts = []}", 
    "status" : "error", 
    "type" : [ "message-processor" ], 
    "uUID" : "f2ee6ab4-a108-4465-a7ba-b56530d8e3fc" 
    }, { 
    "error" : "com.apigee.kernel.exceptions.spi.UncheckedException{ code = application.bootstrap.FailedToConfigure, message = Configuration failed, associated contexts = []}", 
    "status" : "error", 
    "type" : [ "message-processor" ], 
    "uUID" : "0f41991e-b310-4e77-aac5-5fdb150ef9f6" 
    },
    
  3. در خروجی وضعیت استقرار، پیام خطای «پیکربندی ناموفق» را در هر یک از پردازشگرهای پیام مشاهده خواهید کرد.

  4. به یکی از پردازشگر(های) پیام وارد شوید و log /opt/apigee/var/log/edge-message-processor/logs/system.log را بررسی کنید. ببینید آیا در هنگام استقرار پروکسی API خطایی وجود دارد یا خیر.

  5. بسته به خطا/استثنای مشاهده شده در گزارش پردازشگر پیام، باید مراحل عیب یابی مناسب و حل مشکل را دنبال کنید.

  6. بخش‌های زیر برخی از متداول‌ترین استثناهای مشاهده شده را که منجر به خطای استقرار " پیکربندی ناموفق" می‌شود، ارائه می‌کند و مراحلی را برای عیب‌یابی و رفع آنها ارائه می‌کند.

علت: از دست رفتن کلاس جاوا در خط مشی JavaCallout

تشخیص

  1. در گزارش‌های پردازشگر پیام، اگر در حین استقرار یک پراکسی API (DeployEvent) مانند شکل زیر، استثنایی با پیام "Failed to instantiate the JavaCallout Class" مشاهده کردید، سپس به مرحله 2 بروید. اگر نه، به عملوندهای نادرست استفاده شده در شرایط موجود در Condition Flow بروید.
  2. پردازشگر پیام، استثنای زیر را در هنگام استقرار پروکسی API نشان می دهد:

    2017-10-10 05:02:42,330 Apigee-Main-5 ERROR MESSAGING.CONFIGURATION - MessageProcessorServiceImpl.configure() : error configuring config events [DeployEvent{organization='myorg', application='oauth2', applicationRevision='14', deploymentSpec=basepath=/;env=dev;, deploymentID=null}] 
    com.apigee.kernel.exceptions.spi.UncheckedException: Failed to instantiate the JavaCallout Class com.something.apigee.callout.crypto.main.SecretCallout 
    at com.apigee.steps.javacallout.JavaCalloutStepDefinition.newInstance(JavaCalloutStepDefinition.java:89) ~[javacallout-1.0.0.jar:na] 
    at com.apigee.messaging.runtime.StepDefinition.getStepDefinitionExecution(StepDefinition.java:230) ~[message-processor-1.0.0.jar:na] 
    …
    <snipped>
    
  3. پیام خطا در استثنای بالا نشان می دهد که کلاس JavaCallout com.something.apigee.callout.crypto.main.SecretCallout نمی تواند نمونه سازی شود. این خطا معمولاً زمانی رخ می دهد که کلاس خاص در فایل JAR مشخص شده در خط مشی JavaCallout یا هر یک از فایل های JAR وابسته به آن موجود نباشد.

  4. فایل JAR را که حاوی تمام کلاس‌های مربوط به بسته com.something.apigee.callout.crypto.main است بررسی کنید و تأیید کنید که کلاس خاص com.something.apigee.callout.crypto.main.SecretCallout وجود ندارد.

وضوح

  1. کلاس گم شده را به فایل JAR خاص اضافه کنید و فایل JAR را آپلود کنید.
  2. پراکسی API را مجدداً مستقر کنید.
  3. در مثال بالا، مشکل را با این روش حل کردیم:
    1. افزودن کلاس گمشده com.something.apigee.callout.crypto.main.SecretCallout به فایل JAR.
    2. آپلود فایل JAR به روز شده و استقرار مجدد پروکسی API.

علت: عملوندهای نادرستی که با عملگرها در Condition Flow استفاده می شوند

تشخیص

  1. در گزارش‌های پردازشگر پیام، اگر com.apigee.expressions.parser.ParseException را مشاهده کردید com.apigee.expressions.parser.ParseException در طول استقرار یک پروکسی API یا جریان مشترک همانطور که در پیام های مثال زیر نشان داده شده است، سپس به مرحله 2 بروید. اگر نه، به دلیل بعدی نام میزبان نامعتبر در خط مشی ثبت پیام بروید.

    نمونه پیام خطا

    com.apigee.expressions.parser.ParseException: Both the operands for EQUALS expression should be data expressions
    
    
  2. بیایید به یک مثال نگاه کنیم تا بفهمیم چگونه این موضوع را تشخیص دهیم.

    مثال: عملوندهای عبارت <Operator> باید عبارت داده باشند

  3. پردازشگر پیام استثنای زیر را در هنگام استقرار یک جریان مشترک نشان می دهد:

    2017-11-23 09:11:04,498  Apigee-Main-6 ERROR MESSAGING.RUNTIME - AbstractConfigurator.loadXMLConfigurations() : Unable to Load default for path /organizations/myorg/apiproxies/Introspection/revisions/12/sharedflows/default
    2017-11-23 09:11:04,499  Apigee-Main-6 ERROR MESSAGING.RUNTIME - Application.sync() :  sync error for Introspection and revision 12
    2017-11-23 09:11:04,499  Apigee-Main-6 ERROR MESSAGING.RUNTIME - Application.sync() :  Actual Error
    com.apigee.expressions.parser.ParseException: Both the operands for EQUALS expression should be data expressions
        at com.apigee.expressions.parser.ExpressionParser.buildExpressionTree(ExpressionParser.java:337) ~[expressions-1.0.0.jar:na]
        at com.apigee.expressions.parser.ExpressionParser.parse(ExpressionParser.java:24) ~[expressions-1.0.0.jar:na]
        at com.apigee.expressions.parser.ExpressionParser.parseLogicExpression(ExpressionParser.java:28) ~[expressions-1.0.0.jar:na]
        at com.apigee.messaging.runtime.Step.getExpression(Step.java:67) ~[message-processor-1.0.0.jar:na]
        at com.apigee.messaging.runtime.Step.handleAdd(Step.java:58) ~[message-processor-1.0.0.jar:na]
        at com.apigee.messaging.runtime.SharedFlowRuntime.addStep(SharedFlowRuntime.java:81) ~[message-processor-1.0.0.jar:na] … <snipped>
    
  4. پیغام خطا در ParseException - " Both the operands for EQUALS expression should be data expressions " نشان می دهد که شرطی که برابر با (=) است، نه برابر (!=) یا Stats با (=|) دارای مشکل است.

  5. به شرایط موجود در همه جریان‌های شرایط مربوط به اپراتور خاص ذکر شده در پیام خطا نگاه کنید و ببینید آیا هر یک از مشکلات زیر وجود دارد:

    1. عبارات دو طرف عملگر از یک نوع هستند. برای مثال، اگر یک متغیر رشته ای در سمت چپ عملگر دارید، باید متغیر رشته یا مقدار رشته دیگری را در سمت راست داشته باشید.
    2. از متغیرهای معتبر بین عملگرها استفاده می شود.
    3. بین عملگر و هر یک از عبارات فاصله وجود دارد.

  6. اگر هر یک از معیارهای ذکر شده در بالا برآورده نشد، ParseException را دریافت می کنید - " Both the operands for EQUALS expression should be data expressions ".

  7. برای درک این موضوع به یک مثال نگاه می کنیم. در اینجا یک شرط خطای نمونه وجود دارد

    <Condition>
               (fault.name = "invalid_access_token") or(fault.name = "ApiKeyNotApproved")
    </Condition>
    
  8. در این مثال، می توانید مشاهده کنید که بین عملگر "یا" و سپس شرط بعدی فاصله وجود ندارد. بنابراین وقتی شرط دوم در حال تجزیه است، عبارت اول به عنوان "or(fault.name" برای عملگر EQUALS در نظر گرفته می شود. این نام یک متغیر معتبر نیست، بنابراین به عنوان یک عبارت داده معتبر در نظر گرفته نمی شود. در نتیجه شما این استثنا را دریافت کنید:

    com.apigee.expressions.parser.ParseException: Both the operands for EQUALS expression should be data expressions
    
    

وضوح

  1. اطمینان حاصل کنید که همیشه عبارات داده مناسبی در هر دو طرف عملگرها دارید.
  2. در مثالی که در بالا بحث شد، رزولوشن برای اطمینان از وجود فضای خالی بعد از عملگر "or" بود که در قطعه کد توضیح داده شد:

    <Condition>
               (fault.name = "invalid_access_token") or (fault.name = "ApiKeyNotApproved")
    </Condition>
    
    

نام میزبان در خط مشی MessageLogging نامعتبر است

تشخیص

  1. در سیاهههای مربوط به پردازشگر پیام، اگر در حین استقرار پروکسی API یا جریان اشتراکی مانند شکل زیر، استثنایی با پیام "نام میزبان نامعتبر" مشاهده کردید، سپس به مرحله 2 بروید. اگر نه، به علت بعدی نامعتبر KeyValueMap بروید.

    com.apigee.rest.framework.ValidationException: Invalid syslog config: Invalid HostName 'splunkprod.myorg.com/' for Syslog handler
    
  2. بیایید به دو مثال زیر نگاه کنیم تا نحوه عیب یابی و حل این مشکل را درک کنیم.

مثال 1: نام میزبان دارای کاراکتر ویژه ناخواسته است

  1. پردازشگر پیام، استثنای زیر را در هنگام استقرار پروکسی API نشان می دهد:

      2018-01-20 02:12:13,535 Apigee-Main-3 ERROR MESSAGING.CONFIGURATION - MessageProcessorServiceImpl.configure() : error configuring config events [DeployEvent{organization='myorg', application='providersearch', applicationRevision='4', deploymentSpec=basepath=/;env=prod;, deploymentID=null}] 
      com.apigee.rest.framework.ValidationException: Invalid syslog config: Invalid HostName 'splunkprod.myorg.com/' for Syslog handler 
      at com.apigee.messaging.runtime.destinations.SyslogDestination.<init>(SyslogDestination.java:44) ~[message-processor-1.0.0.jar:na] 
      at com.apigee.messaging.runtime.destinations.SysLoggerFactory.getInstance(SysLoggerFactory.java:39) ~[message-processor-1.0.0.jar:na]
      at com.apigee.messaging.runtime.destinations.DestinationRegistry.newDestination(DestinationRegistry.java:44) ~[message-processor-1.0.0.jar:na] 
      ...<snipped>
    
  2. استثناء بالا نشان می دهد که استقرار به دلیل "نامعتبر نام میزبان "<hostname>" برای کنترل کننده Syslog" ناموفق است. این نشان می دهد که نام میزبان مورد استفاده در خط مشی MessageLogging یک نام میزبان نامعتبر است.

  3. بررسی دقیق استثنا در گزارش پردازشگر پیام نشان می‌دهد که یک کاراکتر ویژه ناخواسته "/" در انتهای HostName 'splunkprod.myorg.com/'.

  4. این کاراکتر ویژه ناخواسته دلیل خطای استقرار بود.

وضوح

  1. خط مشی MessageLogging را برای حذف هر گونه کاراکتر خاص ناخواسته برای حل مشکل تغییر دهید.
  2. در مثال بالا، کاراکتر ویژه "/" از سیاست MessageLogging حذف شد. این موضوع را حل کرد.

مثال 2: نام میزبان غیرقابل حل

  1. گزارش پردازشگر پیام دارای چند خط بود که نشان می‌دهد رویداد استقرار برای یک پراکسی API راه‌اندازی شده است، که به دنبال آن یک استثنا در طول استقرار پروکسی API رخ می‌دهد:

    2017-12-22 00:13:49,057 Apigee-Main-87446 INFO MESSAGING.CONFIGURATION - MessageProcessorServiceImpl.configure() : configuring [DeployEvent{organization='myorg', application='myapi', applicationRevision='42', deploymentSpec=basepath=/;env=dev;, deploymentID=null}] 
    
    2017-12-22 00:13:49,318 Apigee-Main-87446 ERROR c.a.p.h.d.DNSCachedAddress - DNSCachedAddress.refresh() : Unable to resolve host : input-prd.cloud.splunk.com: Name or service not known 
    
    2017-12-22 00:13:49,323 Apigee-Main-87446 ERROR MESSAGING.RUNTIME - AbstractConfigurator.handleUpdate() : Fatal error deploying proxy: {} 
    com.apigee.rest.framework.ValidationException: Invalid syslog config: Invalid HostName 'input-prd.cloud.splunk.com' for Syslog handler 
    at com.apigee.messaging.runtime.destinations.SyslogDestination.<init>(SyslogDestination.java:44) ~[message-processor-1.0.0.jar:na] 
    at com.apigee.messaging.runtime.destinations.SysLoggerFactory.getInstance(SysLoggerFactory.java:39) ~[message-processor-1.0.0.jar:na] 
    at com.apigee.messaging.runtime.destinations.DestinationRegistry.newDestination(DestinationRegistry.java:44) ~[message-processor-1.0.0.jar:na] 
    at com.apigee.steps.messagelogging.MessageLoggingStepDefinition.populateDestinations(MessageLoggingStepDefinition.java:118) ~[message-logging-1.0.0.jar:na] 
    at com.apigee.steps.messagelogging.MessageLoggingStepDefinition.handleAdd(MessageLoggingStepDefinition.java:99) ~[message-logging-1.0.0.jar:na] 
    …
    <snipped> 
    
  2. استثناء بالا نشان می دهد که استقرار به دلیل "نامعتبر نام میزبان "<hostname>" برای کنترل کننده Syslog" ناموفق است.

  3. اگر خط بالای استثنا را بخوانید، می توانید متوجه شوید که پردازشگر پیام قادر به حل نام میزبان 'input-prd.cloud.splunk.com' ارائه شده در خط مشی MessageLogging نیست.

  4. برای تأیید این موضوع، می‌توانید به نام میزبان و پورت # که در خط‌مشی ثبت پیام استفاده می‌شود، از راه دور استفاده کنید.

    1. خط مشی MessageLogging را در ویرایش خاص پروکسی API بررسی کنید و نام میزبان و پورت # استفاده شده را تأیید کنید. در مثال بالا، نام پروکسی API: myapi، revision: 42.

      سیاست ثبت پیام

        <MessageLogging async="false" continueOnError="false" enabled="true" name="Log-To-Splunk">
            <DisplayName>Log-To-Splunk</DisplayName>
            <Syslog>
                <Message>Message.id = {request.header.id}</Message>
                <Host>input-prd.cloud.splunk.com</Host>
                <Port>2900</Port>
                <Protocol>TCP</Protocol>
                <SSLInfo>
                    <Enabled>true</Enabled>
                </SSLInfo>
            </Syslog>
        </MessageLogging>
      
    2. Telnet به میزبان با پورت خاص. برای این مثال، ما telnet را امتحان کردیم و همان خطای موجود در گزارش پردازشگر پیام را دریافت کردیم:

      telnet input-prd.cloud.splunk.com 2900 
      telnet: input-prd.cloud.splunk.com: Name or service not known 
      input-prd.cloud.splunk.com: Host name lookup failure
      
  5. این به وضوح ثابت کرد که نام میزبان قابل حل نیست.

وضوح

  1. سیاست MessageLogging را برای استفاده از نام میزبان معتبر تغییر دهید.

اگر مشکل همچنان ادامه داشت، به «اطلاعات تشخیصی باید جمع‌آوری شود» بروید.

علت: نام KeyValueMap نامعتبر است

تشخیص

  1. در سیاهههای مربوط به پردازشگر پیام، اگر در حین استقرار یک پروکسی API یا جریان اشتراکی، مطابق شکل زیر، استثنایی با پیام "نام KeyValueMap نامعتبر است" مشاهده کردید، سپس به مرحله 2 بروید. اگر نه، به اطلاعات تشخیصی باید جمع آوری شود .

    com.apigee.rest.framework.ValidationException: Invalid syslog config: Invalid HostName 'splunkprod.myorg.com/' for Syslog handler
    
  2. بیایید به یک مثال نگاه کنیم تا بفهمیم چگونه این مشکل را عیب یابی و حل کنیم.

  3. گزارش مثال پردازشگر پیام که استثنا را با پیام "نام KeyValueMap نامعتبر است" نشان می دهد که منجر به خطا در حین استقرار پروکسی API می شود

    2018-02-27 14:14:50,318  Apigee-Main-6 ERROR MESSAGING.RUNTIME - AbstractConfigurator.handleUpdate() : Fatal error deploying proxy: {}
    com.apigee.keyvaluemap.KeyValueMapApiException: KeyValueMap name  is invalid
            at com.apigee.keyvaluemap.service.legacy.KeyValueMapServiceImpl.validateMapName(KeyValueMapServiceImpl.java:125) ~[keyvaluemap-1.0.0.jar:na]
            at com.apigee.keyvaluemap.service.legacy.KeyValueMapServiceImpl.createOrUpdateKeyValueMap(KeyValueMapServiceImpl.java:185) ~[keyvaluemap-1.0.0.jar:na]
            at com.apigee.steps.keyvaluemapoperations.KeyValueMapOperationsStepDefinition.digest(KeyValueMapOperationsStepDefinition.java:180) ~[keyvaluemap-operations-1.0.0.jar:na]
            at com.apigee.steps.keyvaluemapoperations.KeyValueMapOperationsStepDefinition.handleAdd(KeyValueMapOperationsStepDefinition.java:197) ~[keyvaluemap-operations-1.0.0.jar:na]
            at com.apigee.entities.AbstractConfigurator.handleUpdate(AbstractConfigurator.java:130) [config-entities-1.0.0.jar:na]
            at com.apigee.messaging.runtime.Application.handleUpdate(Application.java:229) [message-processor-1.0.0.jar:na]
    
    2018-02-27 14:14:50,344  Apigee-Main-6 ERROR BOOTSTRAP - RuntimeConfigurationServiceImpl.dispatchToListeners() : RuntimeConfigurationServiceImpl.dispatchToListeners : Error occurred while dispatching the request DeployEvent{organization='myorg', application='CustomerAPI', applicationRevision='1', deploymentSpec=basepath=/;env=test;, deploymentID=null} to com.apigee.application.bootstrap.listeners.MessageProcessorBootstrapListener@5009d06e
    com.apigee.keyvaluemap.KeyValueMapApiException: KeyValueMap name  is invalid
            at com.apigee.keyvaluemap.service.legacy.KeyValueMapServiceImpl.validateMapName(KeyValueMapServiceImpl.java:125) ~[keyvaluemap-1.0.0.jar:na]
            at com.apigee.keyvaluemap.service.legacy.KeyValueMapServiceImpl.createOrUpdateKeyValueMap(KeyValueMapServiceImpl.java:185) ~[keyvaluemap-1.0.0.jar:na]
            at com.apigee.steps.keyvaluemapoperations.KeyValueMapOperationsStepDefinition.digest(KeyValueMapOperationsStepDefinition.java:180) ~[keyvaluemap-operations-1.0.0.jar:na]
            at com.apigee.steps.keyvaluemapoperations.KeyValueMapOperationsStepDefinition.handleAdd(KeyValueMapOperationsStepDefinition.java:197) ~[keyvaluemap-operations-1.0.0.jar:na]
            at com.apigee.entities.AbstractConfigurator.handleUpdate(AbstractConfigurator.java:130) ~[config-entities-1.0.0.jar:na]
            at com.apigee.messaging.runtime.Application.handleUpdate(Application.java:229) ~[message-processor-1.0.0.jar:na]
    
  4. دومین استثنا بالا نشان می دهد که خطای استقرار برای API Proxy رخ داده است: CustomerAPI، revision: 1.

  5. با بررسی stacktrace، می توانید متوجه شوید که هنگام اجرای خط مشی KeyValuMapOperations خطایی رخ داده است.

  6. با نگاهی به بسته API Proxy متوجه می‌شوید که یک خط‌مشی KeyValuMapOperations وجود دارد که دارای کدی است که در زیر نشان داده شده است:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <KeyValueMapOperations async="false" continueOnError="false" enabled="true" name="Pulling-Keys" mapIdentifier="">
     <DisplayName>Pulling Keys</DisplayName>
     <Properties/>
     <ExclusiveCache>false</ExclusiveCache>
    
    
  7. همانطور که در بالا مشاهده شد، mapIdentifier که نام KeyValueMap را نشان می دهد، دارای یک رشته خالی است. نام KeyValueMap نمی تواند رشته خالی باشد. این دلیل خطای Deployment بود.

وضوح

  1. سیاست KeyValueMapOperations را تغییر دهید تا یک نام معتبر مناسب برای KeyValueMap داشته باشید.
  2. در مثال بالا، مشکل را با تغییر KeyValueMapOperations برای داشتن نام KeyValueMap به عنوان "MyKeyValueMap" حل کردیم، همانطور که در زیر نشان داده شده است:

      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <KeyValueMapOperations async="false" continueOnError="false" enabled="true" name="Pulling-Keys" mapIdentifier="MyKeyValueMap">
        <DisplayName>Pulling Keys</DisplayName>
        <Properties/>
        <ExclusiveCache>false</ExclusiveCache>
    

باید اطلاعات تشخیصی را جمع آوری کرد

اگر حتی پس از پیروی از دستورالعمل‌های بالا، مشکل همچنان ادامه داشت، لطفاً اطلاعات تشخیصی زیر را جمع‌آوری کنید. با پشتیبانی Apigee Edge تماس بگیرید و اطلاعات جمع آوری شده را در اختیار آنها قرار دهید.

  1. خروجی فرمان

    curl -v <management-server-host>:<port #>/v1/runtime/organizations/<org-name>/environments/<env-name>/apis/<apiproxy-name>/revisions/deployments -u <user>
    
  2. گزارش های پردازشگر پیام

    /opt/apigee/var/log/edge-message-processor/logs/system.log
    
  3. جزئیات مربوط به بخش‌هایی که در این کتاب راهنما امتحان شده‌اند و هر بینش دیگری که به ما در حل سریع این مشکل کمک می‌کند.