You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@sling.apache.org by Carsten Ziegeler <cz...@apache.org> on 2013/07/30 09:18:06 UTC

Rethinking the HC API

Hi,

after looking into the current HC API I'm wondering if we shouldn't the API
differently: what we need is the ability to execute checks, get a result
and it would be nice to have the result available via JMX.

Now, for this we need a HealtCheck interface with a single method check()
returning a result (whatever that is). A HC is an OSGi service with some
service properties, meta data like tags etc. can be managed through these
properties.
Executing a check is as simple as calling this method, executing all checks
looks up all available services and calls the method on each of them.

Registering JMX MBeans can be done by an additional component, getting all
service references for a HC service and using the service properties of a
HC to register an MBean.

So all we need is the HC interface, the result interface (or maybe class)
and the JMX support.
Implementing a HC is then as simple as writing an OSGi service.

On top of that we can add support for scripting etc. where we have a
manager service which registers the scripts (or whatever it is) as HC
services.

WDYT?

Carsten

-- 
Carsten Ziegeler
cziegeler@apache.org

Re: Rethinking the HC API

Posted by Bertrand Delacretaz <bd...@apache.org>.
On Tue, Jul 30, 2013 at 12:28 PM, Carsten Ziegeler <cz...@apache.org> wrote:
> ...- I'm not sure whether the info part should be part of the result - if it's
> static it can be part of the interface, but I could imagine that it might
> change and be potentially different between executions....

Yes...the static part does come from the HealthCheck definition, and
the execution can add some values dynamically, makes sense.

> - the ID does not need to be part of the interface, this can be part of the
> service registration properties.

ok, let's try that.

> - tags: i think these could be part of the service registration properties
> as well

ok, and then we need a HealthCheckExecutor service that gets and
executes a set of HealthCheck selected by tags.

>
> The benefit of having the info as service reg props is that the
> filtering/checking can be done without really instantiating/getting the
> services.

ok, the above service will do that then.

Thanks for the review and ideas,
-Bertrand

Re: Rethinking the HC API

Posted by Bertrand Delacretaz <bd...@apache.org>.
On Tue, Jul 30, 2013 at 12:34 PM, Carsten Ziegeler <cz...@apache.org> wrote:
> What about adding a status code to the result, like is done in another hc
> tool from Jörg?
>
> https://github.com/joerghoh/cq5-healthcheck/blob/master/api/src/main/java/de/joerghoh/cq5/healthcheck/StatusCode.java

Yes, we could do that, so instead of anythingToReport() the result
would have getStatus(), returning OK or a value that's the maximal log
level of the mini-log (WARN, ERROR etc.)

-Bertrand

Re: Rethinking the HC API

Posted by Carsten Ziegeler <cz...@apache.org>.
What about adding a status code to the result, like is done in another hc
tool from Jörg?

https://github.com/joerghoh/cq5-healthcheck/blob/master/api/src/main/java/de/joerghoh/cq5/healthcheck/StatusCode.java

Regards
Carsten


2013/7/30 Carsten Ziegeler <cz...@apache.org>

> Hi,
> Ok, so how about
>
>>
>> public interface HealthCheck {
>>   HealthCheckResult execute();
>>
>>   // Unique ID (path of the Resource used to define
>>   / this item, OSGi config PID, etc.)
>>   public String getId();
>>
>>   // Tags are used to select HCItems when checking a subset of them
>>   public Set<String> getTags();
>>
>>   // Additional info: name, description, how to fix etc
>>   public Map<String, String> getInfo();
>> }
>>
>> public interface HealthCheckResult  {
>>   public HealthCheck getHealthCheck();
>>   // If this is false, all checks were successful
>>   public boolean anythingToReport();
>>   public List<LogMessage> getLogMessages();
>> }
>>
>> And HealthCheck are just OSGi services.
>>
>>
> Sounds good, except :)
> - I'm not sure whether the info part should be part of the result - if
> it's static it can be part of the interface, but I could imagine that it
> might change and be potentially different between executions.
> - the ID does not need to be part of the interface, this can be part of
> the service registration properties.
> - tags: i think these could be part of the service registration properties
> as well
>
> The benefit of having the info as service reg props is that the
> filtering/checking can be done without really instantiating/getting the
> services.
>
> Regards
> Carsten
> --
> Carsten Ziegeler
> cziegeler@apache.org
>



-- 
Carsten Ziegeler
cziegeler@apache.org

Re: Rethinking the HC API

Posted by Carsten Ziegeler <cz...@apache.org>.
Hi,
Ok, so how about

>
> public interface HealthCheck {
>   HealthCheckResult execute();
>
>   // Unique ID (path of the Resource used to define
>   / this item, OSGi config PID, etc.)
>   public String getId();
>
>   // Tags are used to select HCItems when checking a subset of them
>   public Set<String> getTags();
>
>   // Additional info: name, description, how to fix etc
>   public Map<String, String> getInfo();
> }
>
> public interface HealthCheckResult  {
>   public HealthCheck getHealthCheck();
>   // If this is false, all checks were successful
>   public boolean anythingToReport();
>   public List<LogMessage> getLogMessages();
> }
>
> And HealthCheck are just OSGi services.
>
>
Sounds good, except :)
- I'm not sure whether the info part should be part of the result - if it's
static it can be part of the interface, but I could imagine that it might
change and be potentially different between executions.
- the ID does not need to be part of the interface, this can be part of the
service registration properties.
- tags: i think these could be part of the service registration properties
as well

The benefit of having the info as service reg props is that the
filtering/checking can be done without really instantiating/getting the
services.

Regards
Carsten
-- 
Carsten Ziegeler
cziegeler@apache.org

Re: Rethinking the HC API

Posted by Bertrand Delacretaz <bd...@apache.org>.
Hi Carsten,

On Tue, Jul 30, 2013 at 11:12 AM, Carsten Ziegeler <cz...@apache.org> wrote:
>... I think there isn't necessarily a 1:1 mapping between a check and an
> expression, e.g. if you have a check for "are all bundles active" this is
> very hard to express as an expression...

Not really, it can be either

  hc.osgi.inactiveBundlesCount == 0

or

  hc.osgi.inactiveBundlesList.isEmpty()

but I see your point, having a generic HealthCheck service makes
sense, I'll draft that below.

> I also would avoid the name "rule" for this - it's a check :)

ok

> We need some result, I'm not sure whether restricting this to a boolean is
> flexible enough. For example if you have a check for available free memory,
> just returning a boolean might not be enough. Maybe we also want to support
> additional information like "this looks wrong ,please check here and there"

Yes, that's the purpose of the mini-logs that the current code is
using, I think those are very useful, for the free memory example the
mini-log might output

  INFO MBean java.lang:service=memory attribute=heap value=123456
  WARN 123456 is less than configured limit 123457, check fails

That's already implemented and also returned as part of MBean output,
and we can easily add INFO messages with recommendation about how to
fix things. Any log message at or above WARN causes the rule to fail,
which also makes it simpler to detect problems in rule evaluation.

> ...Please note, I'm not talking about how to implement a check - this can be
> done through the scripts you already have - right now I'm just talking
> about the consumer API of such a check...

Ok, so how about

public interface HealthCheck {
  HealthCheckResult execute();

  // Unique ID (path of the Resource used to define
  / this item, OSGi config PID, etc.)
  public String getId();

  // Tags are used to select HCItems when checking a subset of them
  public Set<String> getTags();

  // Additional info: name, description, how to fix etc
  public Map<String, String> getInfo();
}

public interface HealthCheckResult  {
  public HealthCheck getHealthCheck();
  // If this is false, all checks were successful
  public boolean anythingToReport();
  public List<LogMessage> getLogMessages();
}

And HealthCheck are just OSGi services.

-Bertrand

Re: Rethinking the HC API

Posted by Carsten Ziegeler <cz...@apache.org>.
2013/7/30 Bertrand Delacretaz <bd...@apache.org>

> Hi Carsten,
>
> On Tue, Jul 30, 2013 at 9:18 AM, Carsten Ziegeler <cz...@apache.org>
> wrote:
> > ...after looking into the current HC API I'm wondering if we shouldn't
> the API
> > differently: what we need is the ability to execute checks, get a result
> > and it would be nice to have the result available via JMX....
>
> Yes - the current prototype has mostly been improvised as the ideas
> came up, and since adding scripted rules yesterday (see [1] for an
> example) I think we could reduce the whole thing to something like:
>
> A Rule has a name, description, an expression and a verify() method
> that returns true or false.
>
> The expression is a snippet of ecmascript code, for example
>
>   jmx.attribute("java.lang:type=ClassLoading", "LoadedClassCount") > 100
>   && hc.osgi.frameworkStartLevel > 1
>
>
I think there isn't necessarily a 1:1 mapping between a check and an
expression, e.g. if you have a check for "are all bundles active" this is
very hard to express as an expression. And for a consumer / invoker of this
check, this is irrelevant whether the check is done through an expression
or java code or what ever it is.

I also would avoid the name "rule" for this - it's a check :) I agree that
name and description can be added as service properties to the registration
of that check service.

We need some result, I'm not sure whether restricting this to a boolean is
flexible enough. For example if you have a check for available free memory,
just returning a boolean might not be enough. Maybe we also want to support
additional information like "this looks wrong ,please check here and there"

Where jmx is an ecmascript context object that provides access to any
> JMX attribute, and hc is another context object that provides
> simplified names for common JMX MBeans. In this example
> hc.osgi.frameworkStartLevel maps to JMX ObjectName =
> "osgi.core:type=framework,version=1.5" attributeName
> ="FrameworkStartLevel". This mapping is defined in an OSGi
> configuration of the hc context object.
>
> Rules can be executed via JMX as in the current prototype, with one
> MBean per rule, see "JMX access to Health Check Rules results" at
> http://sling.apache.org/documentation/bundles/sling-health-check-tool.html
>
> I think we can restrict the whole thing to using JMX MBeans as input,
> which promotes creating more MBeans instead of inventing our own
> management objects. If needed we can easily provide extension points
> to add more ecmascript context objects besides jmx and hc, but I'd
> start with just those to try and keep things simple.
>
> I don't think we can restrict the input to JMX information - and I also
would try to separate the concerns and delegating registration of a check
as an MBean to someone else.

Please note, I'm not talking about how to implement a check - this can be
done through the scripts you already have - right now I'm just talking
about the consumer API of such a check.

Regards
Carsten



> WDYT?
> -Bertrand
>
> [1]
> https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/ecma-jmx-and.json
>



-- 
Carsten Ziegeler
cziegeler@apache.org

Re: Rethinking the HC API

Posted by Bertrand Delacretaz <bd...@apache.org>.
Hi Carsten,

On Tue, Jul 30, 2013 at 9:18 AM, Carsten Ziegeler <cz...@apache.org> wrote:
> ...after looking into the current HC API I'm wondering if we shouldn't the API
> differently: what we need is the ability to execute checks, get a result
> and it would be nice to have the result available via JMX....

Yes - the current prototype has mostly been improvised as the ideas
came up, and since adding scripted rules yesterday (see [1] for an
example) I think we could reduce the whole thing to something like:

A Rule has a name, description, an expression and a verify() method
that returns true or false.

The expression is a snippet of ecmascript code, for example

  jmx.attribute("java.lang:type=ClassLoading", "LoadedClassCount") > 100
  && hc.osgi.frameworkStartLevel > 1

Where jmx is an ecmascript context object that provides access to any
JMX attribute, and hc is another context object that provides
simplified names for common JMX MBeans. In this example
hc.osgi.frameworkStartLevel maps to JMX ObjectName =
"osgi.core:type=framework,version=1.5" attributeName
="FrameworkStartLevel". This mapping is defined in an OSGi
configuration of the hc context object.

Rules can be executed via JMX as in the current prototype, with one
MBean per rule, see "JMX access to Health Check Rules results" at
http://sling.apache.org/documentation/bundles/sling-health-check-tool.html

I think we can restrict the whole thing to using JMX MBeans as input,
which promotes creating more MBeans instead of inventing our own
management objects. If needed we can easily provide extension points
to add more ecmascript context objects besides jmx and hc, but I'd
start with just those to try and keep things simple.

WDYT?
-Bertrand

[1] https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/ecma-jmx-and.json