Skip to content
Snippets Groups Projects
Debug.rst 10.8 KiB
Newer Older
.. ==================================================
.. ==================================================
.. ==================================================
.. Header hierarchy
.. ==
..  --
..   ^^
..    ""
..     ;;
..      ,,
..
.. --------------------------------------------used to the update the records specified ------
.. Best Practice T3 reST: https://docs.typo3.org/m/typo3/docs-how-to-document/master/en-us/WritingReST/CheatSheet.html
..             Reference: https://docs.typo3.org/m/typo3/docs-how-to-document/master/en-us/WritingReST/Index.html
.. Italic *italic*
.. Bold **bold**
.. Code ``text``
.. External Links: `Bootstrap <http://getbootstrap.com/>`_
.. Internal Link: :ref:`downloadButton` (default url text) or :ref:`download Button<downloadButton>` (explicit url text)
.. Add Images:    .. image:: ../Images/a4.jpg
..
..
.. Admonitions
..           .. note::   .. important::     .. tip::     .. warning::
.. Color:   (blue)       (orange)           (green)      (red)
..
.. Definition:
.. some text becomes strong (only one line)
..      description has to indented

.. -*- coding: utf-8 -*- with BOM.

.. include:: Includes.txt


.. _debug:

Debug
=====

.. _QFQ_LOG:

QFQ Log
-------

Setup in :ref:`configuration`

* *qfqLog*

  * Filename where to log QFQ debug and error messages.
  * File is relative to the `<site path>` or absolute (starting with '/').
  * Content: error situations of QFQ and debug, if enabled.

All non SQL related information will be logged to QFQ log file.

.. _SQL_LOG:

SQL Log
-------

Setup in :ref:`configuration`

* *sqlLog*

  * Filename where to log SQL queries and statistical data.
  * File is relative to the `<site path>` or absolute (starting with '/').
  * Content: SQL queries and timestamp, formName/formId, fe_user, success, affected rows, newly created record
    id's and accessed from IP.
  * The global setting can be overwritten by defining `sqlLog` inside of a QFQ tt-content record.


.. _SQL_LOG_MODE:

* *sqlLogMode: all|modify|error|none*

  * *all*: logs every SQL statement.
  * *modify*: logs only statements who might potentially change data.
  * *error*: logs only queries which generate SQL errors.
  * *none*: no query logging at all.
  * The global setting can be overwritten by defining `sqlLogMode` inside of a QFQ tt-content record.

* *showDebugInfo = [yes|no|auto],[download]*

  If active, displays additional information in the Frontend (FE). This is typically helpful during development.

  * *yes*:

    * Form:

      * For every internal link/button, show tooltips with decoded SIP on mouseover.
      * Shows an 'Edit form'-button (wrench symbol) on a form. The link points to the T3 page with the :ref:`form-editor`.

    * Report: Will be configured per tt-content record.

      *debugShowBodyText = 1*

  * *no*: No debug info.

  * *auto*: Depending if there is a Typo3 BE session, set internally:

    * *showDebugInfo = yes*  (BE session exist)
    * *showDebugInfo = no*   (no BE session)

  * *download*:

    * During a download (especially by using wkhtml), temporary files are not deleted automatically. Also the
      ``wkhtmltopdf``, ``pdfunite``, ``pdf2img`` command lines will be logged to :ref:`QFQ_LOG`. Use this only to debug problems on download.

.. _MAIL_LOG:

MAIL Log
--------

Setup in :ref:`configuration`

* *mailLog*

  * File which `sendEmail` logs sending mail.
  * File is relative to the `<site path>` or absolute (starting with '/').


.. _`mail-log-page`:

Mail Log page (Table MailLog)
-----------------------------

For debugging purposes you may like to add a Mail Log page in the frontend.
The following QFQ code could be used for that purpose (put it in a QFQ PageContent element)

Carsten  Rose's avatar
Carsten Rose committed
.. warning::

Use this code only on access restricted pages. GET/POST Parameter might be used to get access to unintended content.


Note: If you do not use/have the Ggroup table, then remove the "# Filters" block.::

    # Page parameters
    1.sql = SELECT @grId := '{{grId:C0:digit}}' AS _grId
    2.sql = SELECT @summary := IF('{{summary:CE:alnumx}}' = 'true', 'true', 'false') AS _s

    # Filters
    10 {
      sql = SELECT "'", gr.id, IF(gr.id = @grId, "' selected>", "'>"), gr.value, ' (Id: ', gr.id, ')'
               FROM Ggroup AS gr
               INNER JOIN MailLog AS ml ON ml.grId = gr.id
               GROUP BY gr.id
      head = <form onchange='this.submit();' class='form-inline'><input type='hidden' name='id' value='{{pageAlias:T0}}'>
               Filter By Group: <select name='grId' class='form-control'><option value=''></option>
      rbeg = <option value=
      rend = </option>
      tail = </select>
    }

    20 {
      sql = SELECT IF(@summary = 'true', ' checked', '')
      head = <div class='checkbox'><label><input type='checkbox' name='summary' value='true'
      tail = >Summary</label></div></form>
    }

    # Mail Log
    50 {
      sql = SELECT id, '</td><td>', grId, '</td><td>', xId, '</td><td>'
                   , REPLACE(receiver, ',', '<br>'), '</td><td>', REPLACE(sender, ',', '<br>'), '</td><td>'
                   , DATE_FORMAT(modified, '%d.%m.%Y<br>%H:%i:%s'), '</td><td style="word-break:break-word;">'
                   , CONCAT('<b>', subject, '</b><br>', IF(@summary = 'true', CONCAT(SUBSTR(body, 1
                            , LEAST(IF(INSTR(body, '\n') = 0, 50, INSTR(body, '\n')), IF(INSTR(body, '<br>') = 0, 50
                            , INSTR(body, '<br>')))-1), ' ...'), CONCAT('<br>', REPLACE(body, '\n', '<br>'))) )
              FROM MailLog
              WHERE (grId = @grId OR @grId = 0)
              ORDER BY modified DESC
              LIMIT 100
      head = <table class="table table-condensed table-hover"><tr>
                 <th>Id</th><th>grId</th><th>xId</th><th>To</th><th>From</th><th>Date</th><th>E-Mail</th></tr>
      tail = </table>
      rbeg = <tr><td>
      rend = </td></tr>
    }

.. _REDIRECT_ALL_MAIL_TO:

Redirect all mail to (catch all)
--------------------------------

Setup in :ref:`configuration`

* *redirectAllMailTo=john@doe.com*

  * During the development, it might be helpful to configure a 'catch all' email address, which QFQ uses as the final receiver
    instead of the original intended one.

  * The setting will:

    * Replace the 'To' with the configured one.
    * Clear 'CC' and 'Bcc'
    * Write a note and the original configured receiver at the top of the email body.


Show log files realtime
-----------------------

Carsten  Rose's avatar
Carsten Rose committed
.. warning::

Use this code only on access restricted pages. GET/POST Parameter might be used to get access to unintended content.
Carsten  Rose's avatar
Carsten Rose committed
Display QFQ log files in realtime. Put the following code in a QFQ page content element.::

   #
   # {{logfile:SU}}
   #

   # Show buttons to select log file.
   10 {
     sql = SELECT '{{logfile:SU:::sql.log}}' AS '_=logfile'
     head = <p>
     tail = </p>

     20.sql = SELECT CONCAT('p:{{pageAlias:T}}&logfile=sql.log|t:sql.log|b:', IF('{{logfile:R}}'='sql.log','primary','')) AS _page, ' '
                     , CONCAT('p:{{pageAlias:T}}&logfile=qfq.log|t:qfq.log|b:', IF('{{logfile:R}}'='qfq.log','primary','')) AS _page, ' '
                     , CONCAT('p:{{pageAlias:T}}&logfile=mail.log|t:mail.log|b:', IF('{{logfile:R}}'='mail.log','primary','')) AS _page
   }

   # Show selected log file.
   100 {
     sql = SELECT 'file:{{qfqProjectPath:Y}}/log/{{logfile:R}}' AS _monitor
     head = <pre id="monitor-1">Please wait</pre>
   }

**NOTE**: The `log` directory has been moved into `qfqProject` with a recent upgrade of QFQ. For backwards compatibility logs are still stored in `fileadmin/protected/log/` if that directory already exists.

.. _`form-submit-log-page`:

Form Submit Log page
--------------------

Carsten  Rose's avatar
Carsten Rose committed
.. warning::

Use this code only on access restricted pages. GET/POST Parameter might be used to get access to unintended content.

Check the Form Submit Log page to see what have been submitted. Put the following code in a QFQ page content element.::

    #
    # Show all form submit. Optional filter by Form or FeUser.
    #
    # {{formId:SC0}}
    # {{feUser:SCE:alnumx}}
Carsten  Rose's avatar
Carsten Rose committed
    10 {
      sql = SELECT ''
      shead = <form onchange='this.submit()' class='form-inline'><input type='hidden' name='id' value='{{pageAlias:T0}}'>
      stail = </form>

      # Dropdown: Form
      20 {

        sql = SELECT "'", f.id, IF( f.id = '{{formId:SC0}}', "' selected>", "'>"), f.name, ' (', QIFEMPTY(COUNT(fsl.id),'-'), ')'
                FROM Form AS f
                LEFT JOIN FormSubmitLog AS fsl
                  ON fsl.formId=f.id
                GROUP BY f.id
                ORDER BY f.name
        head = <label for='formId'>Form:</label> <select name='formId' id='formId' class='form-control'><option value=0></option>
        tail = </select>
        rbeg = <option value=
        rend = </option>
      }

      # Dropdown: feUser
      30 {
        sql = SELECT feUser, IF(feUser = '{{feUser:SCE:alnumx}}', "' selected>", "'>"), feUser, ' (', COUNT(id), ')'
                FROM FormSubmitLog
                WHERE feUser!=''
                GROUP BY feUser
                ORDER BY feUser
        head = <label for='feUser'>FE User:</label> <select name='feUser' id='feUser' class='form-control'><option value=''></option>
        tail = </select>
        rbeg = <option value='
        # just to sync syntax highlighter: '
        rend = </option>
      }
    }

    # Show Log
    50 {
      sql = SELECT l.id
Carsten  Rose's avatar
Carsten Rose committed
                    , CONCAT('<b>Form</b>: ', f.name
                             , '<br><b>Record Id</b>: ', l.recordId
                             , '<br><b>Fe User</b>: ', l.feUser
                             , '<br><b>Date</b>: ', l.created
                             , '<br><b>Page Id</b>: ', l.pageId
                             , '<br><b>Session Id</b>: ', l.sessionId
                             , '<br><b>IP Address</b>: ', l.clientIp
                             , '<br><b>User Agent</b>: ', l.userAgent
                             , '<br><b>SIP Data</b>: <div style="margin-left:20px;">'
                             , "<script>var data = JSON.parse('", l.sipData, "'); for (var key in data) {
                                document.write('<b>' + key + '</b>: ' + data[key] + '<br>'); }</script>", '</div>')
Carsten  Rose's avatar
Carsten Rose committed
                     , CONCAT("<script>var data = JSON.parse('", l.formData, "'); for (var key in data) {
                                document.write('<b>' + key + '</b>: ' + data[key] + '<br>'); }</script>")
                FROM FormSubmitLog AS l
                LEFT JOIN Form AS f
                  ON f.id = l.formId
                WHERE (l.formId = '{{formId:SC0}}' OR '{{formId:SC0}}' = 0)
                  AND (l.feUser = '{{feUser:SCE:alnumx}}' OR '{{feUser:SCE:alnumx}}' = '')
                ORDER BY l.created DESC
                LIMIT 100
      head = <table class="table table-hover">
             <tr><th>Id</th><th style="min-width:250px;">Environment</th><th>Submitted Data</th>
      tail = </table>
      rbeg = <tr>
      renr = </tr>
      fbeg = <td>
      fend = </td>
    }