//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

=== Troubleshooting, Debugging, Profiling, and Monitoring

==== Troubleshooting

===== Logging

Logging is easy to control through the console, with commands grouped under `log` shell. To learn about the available
logging commands type:

----
karaf@root> log<tab>

log:display              log:display-exception    log:get                  log:set
karaf@root>
----

Typical usage is:
 
. Use `log:set` to dynamically change the global log level
. Execute the problematic operation
. Use `log:display` (or `log:display-exception` to display the log

===== Worst Case Scenario

If you end up with a Karaf in a really bad state (i.e. you can not boot it anymore) or you just want to revert to a
clean state quickly, you can safely remove the `data` directory just in the installation directory.  This folder
contains transient data and will be recreated if removed when you relaunch Karaf.
You may also want to remove the files in the `deploy` folder to avoid them being automatically installed when Karaf
is started the first time.

==== Debugging

Usually, the easiest way to debug Karaf or any application deployed onto it is to use remote debugging.
Remote debugging can be easily activated by using the `debug` parameter on the command line.

----
> bin/karaf debug
----

or on Windows

----
> bin\karaf.bat debug
----

Another option is to set the `KARAF_DEBUG` environment variable to `TRUE`.

This can be done using the following command on Unix systems:

----
export KARAF_DEBUG=true
----

On Windows, use the following command

----
set KARAF_DEBUG=true
----

Then, you can launch Karaf using the usual way:

----
bin/karaf
----

or

----
bin\karaf.bat
----

Last, inside your IDE, connect to the remote application (the default port to connect to is 5005).

This option works fine when it is needed to debug a project deployed top of Apache Karaf. Nervertheless, you will be blocked
if you would like to debug the server Karaf. In this case, you can change the following parameter suspend=y in the
karaf.bat script file. That will cause the JVM to pause just before running main() until you attach a debugger then it
will resume the execution.  This way you can set your breakpoints anywhere in the code and you should hit them no matter
how early in the startup they are.

----
export DEFAULT_JAVA_DEBUG_OPTS='-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005'
----

and on Windows,

----
set DEFAULT_JAVA_DEBUG_OPTS='-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005'
----

==== Profiling

===== jVisualVM

You have to edit the `etc/config.properties` configuration file to add the jVisualVM package:

----
org.osgi.framework.bootdelegation=...,org.netbeans.lib.profiler.server
----

Run Karaf from the console, and you should now be able to connect using jVisualVM.

===== YourKit

You need a few steps to be able to profile Karaf using YourKit.

The first one is to edit the `etc/config.properties` configuration file and add the following property:

----
org.osgi.framework.bootdelegation=...,com.yourkit.*
----

Then, set the `JAVA_OPTS` environment variable:

----
export JAVA_OPTS='-Xmx512M -agentlib:yjpagent'
----

or, on Windows

----
set JAVA_OPTS='-Xmx512M -agentlib:yjpagent'
----

Run Karaf from the console, and you should now be able to connect using YourKit standalone or from your favorite IDE.

==== Monitoring

Karaf uses JMX for monitoring and management of all Karaf components.

The JMX connection could be:

* local using the process id

image::jconsole_connect.jpg[]

* remote using the `rmiRegistryPort` property defined in `etc/org.apache.karaf.management.cfg` file.

Using JMX, you can have a clean overview of the running Karaf instance:

* A overview with graphics displaying the load in terms of thread, heap/GC, etc:

image::jconsole_overview.jpg[]

* A thread overview:

image::jconsole_threads.jpg[]

* A memory heap consumption, including "Perform GC" button:

image::jconsole_memory.jpg[]

* A complete JVM summary, with all number of threads, etc:

image::jconsole_summary.jpg[]

You can manage Karaf features like you are in the shell. For example, you have access to the Admin service MBean,
allowing you to create, rename, destroy, change SSH port, etc. Karaf instances:

image::jconsole_admin.jpg[]

You can also manage Karaf features MBean to list, install, and uninstall Karaf features:

image::jconsole_features.jpg[]
