From 98e34db777ac15f6c4d5eea48b054d462caaf012 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Mon, 13 Jan 2025 16:25:24 +0100 Subject: [PATCH] Issue #3475570 by valthebald, mkalkbrenner: Solr-based alternative to dblog --- .github/workflows/jump-start-config-sets.yml | 6 +- .../search_api.index.search_api_solr_log.yml | 160 ++ ..._api.server.search_api_solr_log_server.yml | 48 + .../views.view.search_api_solr_log.yml | 2141 +++++++++++++++++ .../search_api_solr_log.info.yml | 9 + .../search_api_solr_log.module | 8 + .../search_api_solr_log.services.yml | 7 + .../search_api_solr_log.views.inc | 13 + .../src/Logger/SolrLogger.php | 141 ++ .../src/Plugin/views/field/LogMessage.php | 78 + .../src/Plugin/views/field/LogSeverity.php | 40 + .../src/Plugin/views/field/LogUser.php | 37 + 12 files changed, 2685 insertions(+), 3 deletions(-) create mode 100644 modules/search_api_solr_log/config/optional/search_api.index.search_api_solr_log.yml create mode 100644 modules/search_api_solr_log/config/optional/search_api.server.search_api_solr_log_server.yml create mode 100644 modules/search_api_solr_log/config/optional/views.view.search_api_solr_log.yml create mode 100644 modules/search_api_solr_log/search_api_solr_log.info.yml create mode 100644 modules/search_api_solr_log/search_api_solr_log.module create mode 100644 modules/search_api_solr_log/search_api_solr_log.services.yml create mode 100644 modules/search_api_solr_log/search_api_solr_log.views.inc create mode 100644 modules/search_api_solr_log/src/Logger/SolrLogger.php create mode 100644 modules/search_api_solr_log/src/Plugin/views/field/LogMessage.php create mode 100644 modules/search_api_solr_log/src/Plugin/views/field/LogSeverity.php create mode 100644 modules/search_api_solr_log/src/Plugin/views/field/LogUser.php diff --git a/.github/workflows/jump-start-config-sets.yml b/.github/workflows/jump-start-config-sets.yml index 0873982d..4894ed78 100644 --- a/.github/workflows/jump-start-config-sets.yml +++ b/.github/workflows/jump-start-config-sets.yml @@ -255,7 +255,7 @@ jobs: cd drupal php -S localhost:8888 >& /dev/null & vendor/bin/drush si standard --db-url=sqlite://sites/default/files/db.sqlite --yes - vendor/bin/drush en search_api_solr_admin,search_api_solr_devel,search_api_solr_legacy,search_api_spellcheck,search_api_solr_autocomplete,facets,search_api_location --yes + vendor/bin/drush en search_api_solr_admin,search_api_solr_devel,search_api_solr_legacy,search_api_solr_log,search_api_spellcheck,search_api_solr_autocomplete,facets,search_api_location --yes vendor/bin/phpunit -v -c core --group search_api_solr --exclude-group not_drupal${{ matrix.drupal }},not_solr${{ matrix.solr }} modules/contrib/search_api_solr vendor/bin/drush cim --partial --source=modules/contrib/search_api_solr/jump-start/drupal_configs --yes vendor/bin/drush -v solr-gsc solr_cloud test-config-generation.zip @@ -360,7 +360,7 @@ jobs: rm modules/contrib/search_api_solr/tests/src/Kernel/SearchApiSolrLocationTest.php php -S localhost:8888 >& /dev/null & vendor/bin/drush si standard --db-url=sqlite://sites/default/files/db.sqlite --yes - vendor/bin/drush en search_api_solr_admin,search_api_solr_legacy,search_api_spellcheck,search_api_solr_autocomplete --yes + vendor/bin/drush en search_api_solr_admin,search_api_solr_legacy,search_api_solr_log,search_api_spellcheck,search_api_solr_autocomplete --yes vendor/bin/phpunit -c core --group search_api_solr --exclude-group not_drupal${{ matrix.drupal }},not_solr${{ matrix.solr }} modules/contrib/search_api_solr vendor/bin/drush cim --partial --source=modules/contrib/search_api_solr/jump-start/drupal_configs --yes vendor/bin/drush -v solr-gsc solr_cloud test-config-generation.zip @@ -451,7 +451,7 @@ jobs: cd drupal php -S localhost:8888 >& /dev/null & vendor/bin/drush si standard --db-url=sqlite://sites/default/files/db.sqlite --yes - vendor/bin/drush en search_api_solr_admin,search_api_solr_devel,search_api_solr_legacy --yes + vendor/bin/drush en search_api_solr_admin,search_api_solr_devel,search_api_solr_legacy,search_api_solr_log --yes vendor/bin/phpunit -v -c core --group search_api_solr_legacy --exclude-group not_drupal${{ matrix.drupal }},not_solr${{ matrix.solr }} modules/contrib/search_api_solr/modules/search_api_solr_legacy vendor/bin/drush cim --partial --source=modules/contrib/search_api_solr/jump-start/drupal_configs --yes vendor/bin/drush -v solr-gsc solr_36 test-config-generation.zip diff --git a/modules/search_api_solr_log/config/optional/search_api.index.search_api_solr_log.yml b/modules/search_api_solr_log/config/optional/search_api.index.search_api_solr_log.yml new file mode 100644 index 00000000..71983da2 --- /dev/null +++ b/modules/search_api_solr_log/config/optional/search_api.index.search_api_solr_log.yml @@ -0,0 +1,160 @@ +langcode: en +status: true +dependencies: + config: + - search_api.server.jt_price_list_solr_server + module: + - search_api_solr +third_party_settings: + search_api_solr: + finalize: false + commit_before_finalize: false + commit_after_finalize: false + debug_finalize: false + highlighter: + maxAnalyzedChars: 51200 + fragmenter: gap + usePhraseHighlighter: true + highlightMultiTerm: true + preserveMulti: false + regex: + slop: 0.5 + pattern: blank + maxAnalyzedChars: 10000 + highlight: + mergeContiguous: false + requireFieldMatch: false + snippets: 3 + fragsize: 0 + mlt: + mintf: 1 + mindf: 1 + maxdf: 0 + maxdfpct: 0 + minwl: 0 + maxwl: 0 + maxqt: 100 + maxntp: 2000 + boost: false + interestingTerms: none + term_modifiers: + slop: 3 + fuzzy: 1 + fuzzy_analyzer: true + advanced: + index_prefix: '' + collection: '' + timezone: '' + multilingual: + limit_to_content_language: false + include_language_independent: true + use_language_undefined_as_fallback_language: false + specific_languages: + en: '0' + de: '0' + fr: '0' + pl: '0' + it: '0' + es: '0' + cs: '0' + hu: '0' + ro: '0' + bg: '0' + el: '0' + hr: '0' + sk: '0' + sl: '0' + sr: '0' + nl: '0' + use_universal_collation: false +id: search_api_solr_log +name: 'Solr Log' +description: '' +read_only: true +field_settings: + hostname: + label: Hostname + datasource_id: solr_document + property_path: ss_hostname + type: string + id: + label: Id + datasource_id: solr_document + property_path: id + type: string + index_id: + label: 'Index ID' + datasource_id: solr_document + property_path: index_id + type: string + location: + label: Location + datasource_id: solr_document + property_path: ss_location + type: string + message: + label: Message + datasource_id: solr_document + property_path: tus_message + type: text + message_en: + label: 'Message English' + datasource_id: solr_document + property_path: ts_X3b_en_message + type: text + referer: + label: Referer + datasource_id: solr_document + property_path: ss_referer + type: string + severity: + label: Severity + datasource_id: solr_document + property_path: its_severity + type: integer + timestamp: + label: Timestamp + datasource_id: solr_document + property_path: timestamp + type: date + type: + label: Type + datasource_id: solr_document + property_path: ss_type + type: string + uid: + label: 'User ID' + datasource_id: solr_document + property_path: its_uid + type: integer + variables: + label: Variables + datasource_id: solr_document + property_path: zs_variables + type: string +datasource_settings: + solr_document: + id_field: id + request_handler: '' + default_query: '*:*' + label_field: '' + language_field: '' + url_field: '' +processor_settings: + add_url: { } + aggregated_field: { } + auto_aggregated_fulltext_field: { } + custom_value: { } + entity_type: { } + language_with_fallback: { } + rendered_item: { } + solr_date_range: { } +tracker_settings: + default: + indexing_order: fifo +options: + cron_limit: 50 + delete_on_fail: true + index_directly: false + track_changes_in_references: false +server: jt_price_list_solr_server diff --git a/modules/search_api_solr_log/config/optional/search_api.server.search_api_solr_log_server.yml b/modules/search_api_solr_log/config/optional/search_api.server.search_api_solr_log_server.yml new file mode 100644 index 00000000..b0fc5ad6 --- /dev/null +++ b/modules/search_api_solr_log/config/optional/search_api.server.search_api_solr_log_server.yml @@ -0,0 +1,48 @@ +langcode: en +status: true +dependencies: + module: + - search_api_solr +id: search_api_solr_log_server +name: 'Solr Log Server' +description: 'Adjust the settings to your needs. Note, if you don''t have a dedicated log server, you can use the identical settings of an existing server. But it is important to activate "Advanced / Retrieve result data from Solr".' +backend: search_api_solr +backend_config: + retrieve_data: true + highlight_data: false + site_hash: false + server_prefix: '' + domain: generic + environment: default + connector: standard + connector_config: + scheme: http + host: localhost + port: 8983 + path: / + core: drupal + timeout: 5 + index_timeout: 5 + optimize_timeout: 10 + finalize_timeout: 30 + skip_schema_check: false + solr_version: '' + http_method: AUTO + commit_within: 1000 + jmx: false + jts: false + solr_install_dir: '' + optimize: false + fallback_multiple: false + disabled_field_types: { } + disabled_caches: { } + disabled_request_handlers: + - request_handler_elevate_default_7_0_0 + - request_handler_replicationmaster_default_7_0_0 + - request_handler_replicationslave_default_7_0_0 + disabled_request_dispatchers: + - request_dispatcher_httpcaching_default_7_0_0 + rows: 10 + index_single_documents_fallback_count: 10 + index_empty_text_fields: false + suppress_missing_languages: false diff --git a/modules/search_api_solr_log/config/optional/views.view.search_api_solr_log.yml b/modules/search_api_solr_log/config/optional/views.view.search_api_solr_log.yml new file mode 100644 index 00000000..f007dcb7 --- /dev/null +++ b/modules/search_api_solr_log/config/optional/views.view.search_api_solr_log.yml @@ -0,0 +1,2141 @@ +langcode: en +status: true +dependencies: + config: + - search_api.index.search_api_solr_log + - system.menu.admin + - user.role.administrator + module: + - facets_exposed_filters + - search_api + - search_api_solr_log + - user +id: search_api_solr_log +label: 'Recent log messages (Solr)' +module: views +description: 'View events that have recently been logged.' +tag: '' +base_table: search_api_index_search_api_solr_log +base_field: search_api_id +display: + default: + id: default + display_title: Default + display_plugin: default + position: 0 + display_options: + title: 'Recent log messages (Solr)' + fields: + id: + id: id + table: search_api_index_search_api_solr_log + field: id + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Id + exclude: true + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + severity: + id: severity + table: search_api_index_search_api_solr_log + field: severity + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_numeric + label: Severity + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + set_precision: false + precision: 0 + decimal: . + separator: '' + format_plural: false + format_plural_string: !!binary MQNAY291bnQ= + prefix: '' + suffix: '' + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + format_plural_values: { } + type: + id: type + table: search_api_index_search_api_solr_log + field: type + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Type + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + timestamp: + id: timestamp + table: search_api_index_search_api_solr_log + field: timestamp + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_date + label: Date + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + date_format: short + custom_date_format: '' + timezone: '' + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + variables: + id: variables + table: search_api_index_search_api_solr_log + field: variables + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Variables + exclude: true + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + message: + id: message + table: search_api_index_search_api_solr_log + field: message + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Message + exclude: false + alter: + alter_text: true + text: '{{ message | raw }}' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + replace_variables: 1 + uid: + id: uid + table: search_api_index_search_api_solr_log + field: uid + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_numeric + label: User + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + set_precision: false + precision: 0 + decimal: . + separator: '' + format_plural: false + format_plural_string: !!binary Aw== + prefix: '' + suffix: '' + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + format_plural_values: { } + pager: + type: none + options: + offset: 0 + exposed_form: + type: basic + options: + submit_button: Filter + reset_button: true + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: false + sort_asc_label: Asc + sort_desc_label: Desc + access: + type: role + options: + role: + administrator: administrator + cache: + type: search_api_none + options: { } + empty: { } + sorts: { } + arguments: { } + filters: + index_id: + id: index_id + table: search_api_index_search_api_solr_log + field: index_id + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_string + operator: '=' + value: + min: '' + max: '' + value: search_api_solr_log + group: 1 + exposed: false + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: '' + operator_limit_selection: false + operator_list: { } + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + min_placeholder: '' + max_placeholder: '' + placeholder: '' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + search_api_fulltext: + id: search_api_fulltext + table: search_api_index_search_api_solr_log + field: search_api_fulltext + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_fulltext + operator: and + value: '' + group: 1 + exposed: true + expose: + operator_id: search_api_fulltext_op + label: 'Fulltext search' + description: '' + use_operator: false + operator: search_api_fulltext_op + operator_limit_selection: false + operator_list: { } + identifier: search_api_fulltext + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + administrator: '0' + anonymous: '0' + basic_page_author: '0' + customer: '0' + customer_main_user: '0' + customer_masquerade: '0' + eventmanagement: '0' + shop_marketing_role: '0' + manufacturer_site_author: '0' + price_list_user: '0' + price_list_viewer: '0' + product_manager: '0' + technical_support_role: '0' + blog_author_special: '0' + webfaktura_system_role: '0' + azubi: '0' + expose_fields: false + placeholder: '' + searched_fields_id: search_api_fulltext_searched_fields + value_maxlength: 128 + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + parse_mode: terms + min_length: null + fields: { } + severity: + id: severity + table: search_api_index_search_api_solr_log + field: severity + plugin_id: search_api_numeric + type: + id: type + table: search_api_index_search_api_solr_log + field: type + plugin_id: search_api_string + filter_groups: + operator: AND + groups: + 1: AND + style: + type: default + options: + grouping: { } + row_class: '' + default_row_class: true + row: + type: fields + query: + type: search_api_query + options: + bypass_access: true + skip_access: true + preserve_facet_query_args: false + query_tags: { } + relationships: { } + header: { } + footer: { } + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_interface' + - url + - user.roles + tags: + - 'config:search_api.index.search_api_solr_log' + - 'search_api_list:search_api_solr_log' + search_api_solr_log_details_page: + id: search_api_solr_log_details_page + display_title: 'Event Details' + display_plugin: page + position: 1 + display_options: + title: 'Event Details' + fields: + id: + id: id + table: search_api_index_search_api_solr_log + field: id + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Id + exclude: true + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + type: + id: type + table: search_api_index_search_api_solr_log + field: type + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Type + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + timestamp: + id: timestamp + table: search_api_index_search_api_solr_log + field: timestamp + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_date + label: Date + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + date_format: short + custom_date_format: '' + timezone: '' + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + uid: + id: uid + table: search_api_index_search_api_solr_log + field: uid + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_numeric + label: User + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + set_precision: false + precision: 0 + decimal: . + separator: '' + format_plural: false + format_plural_string: !!binary Aw== + prefix: '' + suffix: '' + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + format_plural_values: { } + location: + id: location + table: search_api_index_search_api_solr_log + field: location + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Location + exclude: false + alter: + alter_text: false + text: '' + make_link: true + path: '{{ location }}' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + referer: + id: referer + table: search_api_index_search_api_solr_log + field: referer + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Referer + exclude: false + alter: + alter_text: false + text: '' + make_link: true + path: '{{ referer }}' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + severity: + id: severity + table: search_api_index_search_api_solr_log + field: severity + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_numeric + label: Severity + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + set_precision: false + precision: 0 + decimal: . + separator: '' + format_plural: false + format_plural_string: !!binary MQNAY291bnQ= + prefix: '' + suffix: '' + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + format_plural_values: { } + hostname: + id: hostname + table: search_api_index_search_api_solr_log + field: hostname + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Hostname + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + variables: + id: variables + table: search_api_index_search_api_solr_log + field: variables + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Variables + exclude: true + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + message: + id: message + table: search_api_index_search_api_solr_log + field: message + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Message + exclude: false + alter: + alter_text: true + text: '{{ message | raw }}' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + replace_variables: 1 + arguments: + id: + id: id + table: search_api_index_search_api_solr_log + field: id + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + default_action: default + exception: + value: all + title_enable: false + title: All + title_enable: false + title: '' + default_argument_type: query_parameter + default_argument_options: + query_param: solr_id + fallback: '' + multiple: and + summary_options: { } + summary: + sort_order: asc + number_of_records: 0 + format: default_summary + specify_validation: false + validate: + type: none + fail: 'not found' + validate_options: { } + break_phrase: false + not: false + filters: + index_id: + id: index_id + table: search_api_index_search_api_solr_log + field: index_id + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_string + operator: '=' + value: + min: '' + max: '' + value: search_api_solr_log + group: 1 + exposed: false + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: '' + operator_limit_selection: false + operator_list: { } + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + min_placeholder: '' + max_placeholder: '' + placeholder: '' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + filter_groups: + operator: AND + groups: + 1: AND + defaults: + title: false + fields: false + arguments: false + filters: false + filter_groups: false + display_description: '' + display_extenders: { } + path: admin/reports/search-api-solr-log/event + menu: + type: none + title: 'Recent log messages (Solr)' + description: '' + weight: 0 + expanded: false + menu_name: admin + parent: system.admin_reports + context: '0' + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_interface' + - url + - user.roles + tags: + - 'config:search_api.index.search_api_solr_log' + - 'search_api_list:search_api_solr_log' + serach_api_solr_log_page: + id: serach_api_solr_log_page + display_title: 'Recent Log Messages' + display_plugin: page + position: 1 + display_options: + fields: + id: + id: id + table: search_api_index_search_api_solr_log + field: id + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Id + exclude: true + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + severity: + id: severity + table: search_api_index_search_api_solr_log + field: severity + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_numeric + label: Severity + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + set_precision: false + precision: 0 + decimal: . + separator: '' + format_plural: false + format_plural_string: !!binary MQNAY291bnQ= + prefix: '' + suffix: '' + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + format_plural_values: { } + type: + id: type + table: search_api_index_search_api_solr_log + field: type + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Type + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + timestamp: + id: timestamp + table: search_api_index_search_api_solr_log + field: timestamp + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_date + label: Date + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + date_format: short + custom_date_format: '' + timezone: '' + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + variables: + id: variables + table: search_api_index_search_api_solr_log + field: variables + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Variables + exclude: true + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + message: + id: message + table: search_api_index_search_api_solr_log + field: message + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api + label: Message + exclude: false + alter: + alter_text: true + text: '{{ message | raw }}' + make_link: true + path: 'admin/reports/search-api-solr-log/event?solr_id={{ id }}' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 56 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: true + trim: true + preserve_tags: '' + html: true + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + replace_variables: 1 + uid: + id: uid + table: search_api_index_search_api_solr_log + field: uid + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_numeric + label: User + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + set_precision: false + precision: 0 + decimal: . + separator: '' + format_plural: false + format_plural_string: !!binary Aw== + prefix: '' + suffix: '' + link_to_item: false + use_highlighting: false + multi_type: separator + multi_separator: ', ' + format_plural_values: { } + filters: + index_id: + id: index_id + table: search_api_index_search_api_solr_log + field: index_id + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_string + operator: '=' + value: + min: '' + max: '' + value: search_api_solr_log + group: 1 + exposed: false + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: '' + operator_limit_selection: false + operator_list: { } + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + min_placeholder: '' + max_placeholder: '' + placeholder: '' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + facets_type: + id: facets_type + table: search_api_index_search_api_solr_log + field: facets_type + relationship: none + group_type: group + admin_label: '' + plugin_id: facets_filter + operator: '=' + value: '' + group: 1 + exposed: true + expose: + operator_id: '' + label: Type + description: '' + use_operator: false + operator: '' + operator_limit_selection: false + operator_list: { } + identifier: type + required: false + remember: false + multiple: true + remember_roles: + authenticated: authenticated + administrator: '0' + anonymous: '0' + basic_page_author: '0' + customer: '0' + customer_main_user: '0' + customer_masquerade: '0' + eventmanagement: '0' + shop_marketing_role: '0' + manufacturer_site_author: '0' + price_list_user: '0' + price_list_viewer: '0' + product_manager: '0' + technical_support_role: '0' + blog_author_special: '0' + webfaktura_system_role: '0' + azubi: '0' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + hierarchy: false + label_display: visible + facet: + query_operator: and + min_count: 1 + show_numbers: true + processor_configs: { } + facets_severity: + id: facets_severity + table: search_api_index_search_api_solr_log + field: facets_severity + relationship: none + group_type: group + admin_label: '' + plugin_id: facets_filter + operator: '=' + value: '' + group: 1 + exposed: true + expose: + operator_id: '' + label: Severity + description: '' + use_operator: false + operator: '' + operator_limit_selection: false + operator_list: { } + identifier: severity + required: false + remember: false + multiple: true + remember_roles: + authenticated: authenticated + administrator: '0' + anonymous: '0' + basic_page_author: '0' + customer: '0' + customer_main_user: '0' + customer_masquerade: '0' + eventmanagement: '0' + shop_marketing_role: '0' + manufacturer_site_author: '0' + price_list_user: '0' + price_list_viewer: '0' + product_manager: '0' + technical_support_role: '0' + blog_author_special: '0' + webfaktura_system_role: '0' + azubi: '0' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + hierarchy: false + label_display: visible + facet: + query_operator: or + min_count: 1 + show_numbers: true + processor_configs: + display_value_widget_order: + weights: + sort: 40 + settings: + sort: ASC + facets_hostname: + id: facets_hostname + table: search_api_index_search_api_solr_log + field: facets_hostname + relationship: none + group_type: group + admin_label: '' + plugin_id: facets_filter + operator: '=' + value: '' + group: 1 + exposed: true + expose: + operator_id: '' + label: Hostname + description: '' + use_operator: false + operator: '' + operator_limit_selection: false + operator_list: { } + identifier: hostname + required: false + remember: false + multiple: true + remember_roles: + authenticated: authenticated + administrator: '0' + anonymous: '0' + basic_page_author: '0' + customer: '0' + customer_main_user: '0' + customer_masquerade: '0' + eventmanagement: '0' + shop_marketing_role: '0' + manufacturer_site_author: '0' + price_list_user: '0' + price_list_viewer: '0' + product_manager: '0' + technical_support_role: '0' + blog_author_special: '0' + webfaktura_system_role: '0' + azubi: '0' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + hierarchy: false + label_display: visible + facet: + query_operator: or + min_count: 1 + show_numbers: true + processor_configs: + raw_value_widget_order: + weights: + sort: 50 + settings: + sort: ASC + facets_timestamp: + id: facets_timestamp + table: search_api_index_search_api_solr_log + field: facets_timestamp + relationship: none + group_type: group + admin_label: '' + plugin_id: facets_filter + operator: '=' + value: '' + group: 1 + exposed: true + expose: + operator_id: '' + label: Date + description: '' + use_operator: false + operator: '' + operator_limit_selection: false + operator_list: { } + identifier: timestamp + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + 0: '0' + administrator: '0' + anonymous: '0' + basic_page_author: '0' + customer: '0' + customer_main_user: '0' + customer_masquerade: '0' + eventmanagement: '0' + shop_marketing_role: '0' + manufacturer_site_author: '0' + price_list_user: '0' + price_list_viewer: '0' + product_manager: '0' + technical_support_role: '0' + blog_author_special: '0' + webfaktura_system_role: '0' + azubi: '0' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + hierarchy: true + label_display: visible + facet: + query_operator: or + min_count: 1 + show_numbers: true + processor_configs: + hierarchy_processor: + weights: + build: 100 + settings: { } + date_item: + weights: + build: 35 + settings: + date_display: actual_date + granularity: '2' + hierarchy: 1 + date_format: '' + hierarchy: date_items + expand_hierarchy: 0 + search_api_fulltext: + id: search_api_fulltext + table: search_api_index_search_api_solr_log + field: search_api_fulltext + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_fulltext + operator: and + value: '' + group: 1 + exposed: true + expose: + operator_id: search_api_fulltext_op + label: 'Fulltext search' + description: '' + use_operator: false + operator: search_api_fulltext_op + operator_limit_selection: false + operator_list: { } + identifier: search_api_fulltext + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + administrator: '0' + anonymous: '0' + basic_page_author: '0' + customer: '0' + customer_main_user: '0' + customer_masquerade: '0' + eventmanagement: '0' + shop_marketing_role: '0' + manufacturer_site_author: '0' + price_list_user: '0' + price_list_viewer: '0' + product_manager: '0' + technical_support_role: '0' + blog_author_special: '0' + webfaktura_system_role: '0' + azubi: '0' + expose_fields: false + placeholder: '' + searched_fields_id: search_api_fulltext_searched_fields + value_maxlength: 128 + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + parse_mode: terms + min_length: null + fields: + - message_en + filter_groups: + operator: AND + groups: + 1: AND + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + columns: + id: id + type: type + timestamp: timestamp + uid: uid + severity: severity + variables: variables + message: message + default: timestamp + info: + id: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + type: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + timestamp: + sortable: true + default_sort_order: desc + align: '' + separator: '' + empty_column: false + responsive: '' + uid: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + severity: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + variables: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + message: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + override: true + sticky: false + summary: '' + empty_table: false + caption: '' + description: '' + row: + type: fields + options: { } + defaults: + style: false + row: false + fields: false + filters: false + filter_groups: false + display_description: '' + display_extenders: { } + path: admin/reports/search-api-solr-log + menu: + type: normal + title: 'Recent log messages (Solr)' + menu_name: admin + parent: system.admin_reports + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_interface' + - url + - url.query_args + - user.roles + tags: + - 'config:search_api.index.search_api_solr_log' + - 'search_api_list:search_api_solr_log' diff --git a/modules/search_api_solr_log/search_api_solr_log.info.yml b/modules/search_api_solr_log/search_api_solr_log.info.yml new file mode 100644 index 00000000..498e935f --- /dev/null +++ b/modules/search_api_solr_log/search_api_solr_log.info.yml @@ -0,0 +1,9 @@ +name: 'Search API Solr Log' +type: module +description: 'Logs system events using Solr.' +core_version_requirement: ^10.2 || ^11.0 +package: 'search_api' +dependencies: + - facets:better_exposed_filters + - search_api_solr:search_api_solr + - views:views diff --git a/modules/search_api_solr_log/search_api_solr_log.module b/modules/search_api_solr_log/search_api_solr_log.module new file mode 100644 index 00000000..e32f5c92 --- /dev/null +++ b/modules/search_api_solr_log/search_api_solr_log.module @@ -0,0 +1,8 @@ + $data + * The views data. + */ +function search_api_solr_log_views_data_alter(array &$data): void { + $data['search_api_index_search_api_solr_log']['severity']['field']['id'] = 'search_api_solr_log_severity'; + $data['search_api_index_search_api_solr_log']['message']['field']['id'] = 'search_api_solr_log_message'; + $data['search_api_index_search_api_solr_log']['uid']['field']['id'] = 'search_api_solr_log_user'; +} diff --git a/modules/search_api_solr_log/src/Logger/SolrLogger.php b/modules/search_api_solr_log/src/Logger/SolrLogger.php new file mode 100644 index 00000000..ff3447cf --- /dev/null +++ b/modules/search_api_solr_log/src/Logger/SolrLogger.php @@ -0,0 +1,141 @@ + 'ss_type', + 'uid' => 'its_uid', + 'message' => 'tus_message', + 'variables' => 'zs_variables', + 'message_en' => 'ts_X3b_en_message', + 'severity' => 'its_severity', + 'link' => 'ss_link', + 'location' => 'ss_location', + 'referer' => 'ss_referer', + 'hostname' => 'ss_hostname', + 'timestamp' => 'dt_timestamp', + ]; + + /** + * Internal flag of successful connection to Solr. + * + * @var bool + */ + protected bool $serviceFunctional = TRUE; + + /** + * Constructor. + * + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + * The entity type manager. + * @param \Drupal\Core\Logger\LogMessageParserInterface $parser + * The parser to use when extracting message variables. + */ + public function __construct( + protected EntityTypeManagerInterface $entityTypeManager, + protected LogMessageParserInterface $parser, + protected Helper $helper, + ) {} + + /** + * {@inheritdoc} + */ + public function log($level, string|\Stringable $message, array $context = []): void { + if (!$this->serviceFunctional) { + return; + } + // Remove backtrace and exception since they may contain + // an unserializable variable. + unset($context['exception']); + try { + $connector = self::getConnector(); + } catch (SearchApiException $e) { + return; + } + if (!$connector) { + return; + } + // Convert PSR3-style messages to \Drupal\Component\Render\FormattableMarkup + // style, so they can be translated too in runtime. + $message_placeholders = $this->parser->parseMessagePlaceholders($message, $context); + $channel = mb_substr($context['channel'], 0, 64); + $values = [ + 'id' => 'search_api_solr_log:' . $channel . ':' . uniqid(), + // This helps to clear/filter the documents. + 'index_id' => 'search_api_solr_log', + static::$logFieldMappings['uid'] => $context['uid'], + static::$logFieldMappings['type'] => $channel, + static::$logFieldMappings['message'] => (string) $message, + static::$logFieldMappings['variables'] => json_encode($message_placeholders, JSON_PRETTY_PRINT), + static::$logFieldMappings['message_en'] => $this->t(Xss::filterAdmin((string) $message), (array) $message_placeholders)->render(), + static::$logFieldMappings['severity'] => $level, + static::$logFieldMappings['link'] => $context['link'], + static::$logFieldMappings['location'] => $context['request_uri'], + static::$logFieldMappings['referer'] => $context['referer'], + static::$logFieldMappings['hostname'] => mb_substr($context['ip'], 0, 128), + static::$logFieldMappings['timestamp'] => $this->helper->formatDate($context['timestamp']), + ]; + $query = $connector->getUpdateQuery(); + $query->addDocument($query->createDocument($values))->addCommit(); + try { + $connector->update($query); + } + catch (\Exception $e) { + // Prevent infinite loop trying to log the message. + $this->serviceFunctional = FALSE; + } + } + + /** + * Get solr connector. + * + * @return \Drupal\search_api_solr\SolrConnectorInterface|null + * Solr connector. + * + * @throws \Drupal\search_api\SearchApiException + */ + public static function getConnector() : ?SolrConnectorInterface { + try { + $index = Index::load('search_api_solr_log'); + if ($index && $index->isActive() && $index->hasValidServer()) { + if ($server = $index->getServerInstance()) { + $backend = $server->getBackend(); + if ($backend instanceof SolrBackendInterface) { + return $backend->getSolrConnector(); + } + } + } + } + catch (\Throwable $e) { + return NULL; + } + + return NULL; + } +} diff --git a/modules/search_api_solr_log/src/Plugin/views/field/LogMessage.php b/modules/search_api_solr_log/src/Plugin/views/field/LogMessage.php new file mode 100644 index 00000000..d399b258 --- /dev/null +++ b/modules/search_api_solr_log/src/Plugin/views/field/LogMessage.php @@ -0,0 +1,78 @@ +options['replace_variables']) { + $this->additional_fields['variables'] = 'variables'; + } + } + + /** + * {@inheritdoc} + */ + protected function defineOptions() { + $options = parent::defineOptions(); + $options['replace_variables'] = ['default' => TRUE]; + + return $options; + } + + /** + * {@inheritdoc} + */ + public function buildOptionsForm(&$form, FormStateInterface $form_state) { + parent::buildOptionsForm($form, $form_state); + + $form['replace_variables'] = [ + '#title' => $this->t('Replace variables'), + '#type' => 'checkbox', + '#default_value' => $this->options['replace_variables'] ?? TRUE, + ]; + } + + /** + * {@inheritdoc} + */ + public function render(ResultRow $values): string { + $value = $this->getValue($values)[0] ?? ''; + + if ($this->options['replace_variables']) { + $variables_json = $values->{'solr_document/zs_variables'}[0] ?? '{}'; + $variables = json_decode($variables_json, TRUE); + + if (isset($variables['@backtrace_string'])) { + $variables['@backtrace_string'] = new FormattableMarkup( + '
@backtrace_string
', $variables + ); + } + + return $this->t(Xss::filterAdmin($value), (array) $variables)->render(); + } + + return $this->sanitizeValue((string) $value); + } + +} diff --git a/modules/search_api_solr_log/src/Plugin/views/field/LogSeverity.php b/modules/search_api_solr_log/src/Plugin/views/field/LogSeverity.php new file mode 100644 index 00000000..b7fd7075 --- /dev/null +++ b/modules/search_api_solr_log/src/Plugin/views/field/LogSeverity.php @@ -0,0 +1,40 @@ + 'debug', + RfcLogLevel::INFO => 'info', + RfcLogLevel::NOTICE => 'notice', + RfcLogLevel::WARNING => 'warning', + RfcLogLevel::ERROR => 'error', + RfcLogLevel::CRITICAL => 'critical', + RfcLogLevel::ALERT => 'alert', + RfcLogLevel::EMERGENCY => 'emergency', + ]; + + /** + * Renders the log level value as a string. + */ + public function render($values): string { + // Retrieve the field value from Search API result. + $value = $this->getValue($values); + return $this->logLevels[$value[0] ?? 999] ?? ''; + } + +} diff --git a/modules/search_api_solr_log/src/Plugin/views/field/LogUser.php b/modules/search_api_solr_log/src/Plugin/views/field/LogUser.php new file mode 100644 index 00000000..ddf9350a --- /dev/null +++ b/modules/search_api_solr_log/src/Plugin/views/field/LogUser.php @@ -0,0 +1,37 @@ +getValue($values)[0] ?? 0; + + // Load the user entity. + $user = User::load($user_id); + + if ($user) { + // Generate the URL to the user profile. + $url = Url::fromRoute('entity.user.canonical', ['user' => $user_id]); + return Link::fromTextAndUrl($user->getDisplayName(), $url)->toString(); + } + + return $this->t('Unknown User')->render(); + } + +}