Self-monitoring of autonomic distributed systems requires knowledge of the states and events of many different parts of a system. One of the main challenges is to determine which information is most crucial for analysis of a system's behaviour, and when. This paper proposes a model- based approach to self-monitoring for which structural and behavioural models of a system are described at different levels: application, subsystem, component and class level. In this approach, a system's behaviour is monitored in the context of a hierarchy of use-cases related to these levels. The structural and behavioural models are used to automatically instrument an existing distributed system. The proposed architecture of a self-monitoring engine is described as is the implementation. The models have been specified in the Ontology Web Language (OWL) and the self-monitoring (as a part of our self-management framework) has been implemented in Java. The scenario used to illustrate the approach is that of authentication for a simplified version of a distributed portal application.