Bug 19542: Add Elasticsearch information in the 'About' page
authorTomas Cohen Arazi <tomascohen@theke.io>
Tue, 31 Oct 2017 14:29:28 +0000 (11:29 -0300)
committerJonathan Druart <jonathan.druart@bugs.koha-community.org>
Mon, 11 Dec 2017 17:30:42 +0000 (14:30 -0300)
This patch adds Elasticsearch related information to the 'About' page.

The information is gathered and displayed only when the 'SearchEngine' syspref
is set to 'Elasticsearch'. It displays configured nodes, and the status:
- Running
- Not running

In case it is running, it displays the defined indices and the document count on each.
If there are configuration problems, exceptions are catch and a convenient warning
message is displayed.

To test:
- Apply this patches
- Run:
  $ kshell
 k$ prove t/Koha/SearchEngine/Elasticsearch.t
=> SUCCESS: Tests pass!
- Have ES configured in your koha-conf.xml file (by default in kohadevbox)
- Set the 'SearchEngine' syspref to 'Elasticsearch'
- Comment out pieces of the elasticsearch-specific entries (server, index_name,
  the whole elasticsearch block). Reload on each change.
=> SUCCESS: Warning messages are displayed and make sense in the context of your changes.
----> the rest of the tests require having ES running on the dev env. This can be easily
      achieved by creating the kohadevbox using:
        $ KOHA_ELASTICSEARCH=1 vagrant up
- Stop the 'elasticsearch' service:
  $ sudo service elasticsearch stop
- Reload about.pl
=> SUCCESS: The configured nodes are displayed, and the status is 'not running'
- Start the 'elasticsearch' service:
  $ sudo service elasticsearch start
- Reload about.pl
=> SUCCESS: The configured nodes are displayed, the status is 'running' and
            created indices info is displayed, along with the document count
            on each index.
- Sign off :-D

Signed-off-by: David Bourgault <david.bourgault@inlibro.com>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>

about.pl
koha-tmpl/intranet-tmpl/prog/en/modules/about.tt

index 5e48173..210a923 100755 (executable)
--- a/about.pl
+++ b/about.pl
@@ -27,6 +27,8 @@ use List::MoreUtils qw/ any /;
 use LWP::Simple;
 use XML::Simple;
 use Config;
+use Search::Elasticsearch;
+use Try::Tiny;
 
 use C4::Output;
 use C4::Auth;
@@ -40,8 +42,11 @@ use Koha::Patrons;
 use Koha::Caches;
 use Koha::Config::SysPrefs;
 use Koha::Illrequest::Config;
+use Koha::SearchEngine::Elasticsearch;
+
 use C4::Members::Statistics;
 
+
 #use Smart::Comments '####';
 
 my $query = new CGI;
@@ -292,6 +297,67 @@ if ( C4::Context->preference('ILLModule') ) {
     $template->param( warnILLConfiguration => $warnILLConfiguration );
 }
 
+if ( C4::Context->preference('SearchEngine') eq 'Elasticsearch' ) {
+    # Check ES configuration health and runtime status
+
+    my $es_status;
+    my $es_config_error;
+    my $es_running = 1;
+
+    my $es_conf;
+    try {
+        $es_conf = Koha::SearchEngine::Elasticsearch::_read_configuration();
+    }
+    catch {
+        if ( ref($_) eq 'Koha::Exceptions::Config::MissingEntry' ) {
+            $template->param( elasticsearch_fatal_config_error => $_->message );
+            $es_config_error = 1;
+        }
+        warn p($_);
+    };
+    if ( !$es_config_error ) {
+
+        my $biblios_index_name     = $es_conf->{index_name} . "_" . $Koha::SearchEngine::BIBLIOS_INDEX;
+        my $authorities_index_name = $es_conf->{index_name} . "_" . $Koha::SearchEngine::AUTHORITIES_INDEX;
+
+        my @indexes = ($biblios_index_name, $authorities_index_name);
+        # TODO: When new indexes get added, we could have other ways to
+        #       fetch the list of available indexes (e.g. plugins, etc)
+        $es_status->{nodes} = $es_conf->{nodes};
+        my $es = Search::Elasticsearch->new({ nodes => $es_conf->{nodes} });
+
+        foreach my $index ( @indexes ) {
+            my $count;
+            try {
+                $count = $es->indices->stats( index => $index )
+                      ->{_all}{primaries}{docs}{count};
+            }
+            catch {
+                if ( ref($_) eq 'Search::Elasticsearch::Error::Missing' ) {
+                    push @{ $es_status->{errors} }, "Index not found ($index)";
+                    $count = -1;
+                }
+                elsif ( ref($_) eq 'Search::Elasticsearch::Error::NoNodes' ) {
+                    $es_running = 0;
+                }
+                else {
+                    # TODO: when time comes, we will cover more use cases
+                    die $_;
+                }
+            };
+
+            push @{ $es_status->{indexes} },
+              {
+                index_name => $index,
+                count      => $count
+              };
+        }
+        $es_status->{running} = $es_running;
+
+        $template->param( elasticsearch_status => $es_status );
+    }
+}
+
 # Sco Patron should not contain any other perms than circulate => self_checkout
 if (  C4::Context->preference('WebBasedSelfCheck')
       and C4::Context->preference('AutoSelfCheckAllowed')
index f54b2d1..132fac1 100644 (file)
@@ -1,4 +1,5 @@
 [% USE HtmlTags %]
+[% USE Koha %]
 [% SET footerjs = 1 %]
 [% INCLUDE 'doc-head-open.inc' %]
 <title>Koha &rsaquo; About Koha</title>
           [% IF (is_psgi) %]
             <tr><th scope="row">PSGI: </th><td>[% psgi_server |html %]</td></tr>
           [% END %]
+          [% IF Koha.Preference('SearchEngine') == 'Elasticsearch' %]
+            <tr>
+                <th scope="row">Elasticsearch: </th>
+            [% IF elasticsearch_fatal_config_error %]
+                <td><span class="status_warn">[% elasticsearch_fatal_config_error %]</span></td>
+            [% ELSE %]
+                <td>
+                    Nodes:
+                    <span>[% elasticsearch_status.nodes.join(' / ') %]</span>
+                    |
+                    Status:
+                [% IF elasticsearch_status.running %]
+                    <span class="status_ok">running</span>
+                    |
+                    Indices:
+                  [% FOREACH index IN elasticsearch_status.indexes %]
+                      [% index.index_name %] (count: <emph>[% index.count %]</emph>)
+                  [% END %]
+                [% ELSE %]
+                    <span class="status_warn">not running</span>
+                [% END %]
+                </td>
+            [% END %]
+            </tr>
+          [% END %]
             <tr><th scope="row">Memcached: </th>
                 <td>
                     Servers: [% IF memcached_servers %]<span>[% memcached_servers | html %]</span>