287
Advanced PATROL Knowledge Module Development BMC Software 9 September 2001

Advanced KM Development

  • Upload
    almas00

  • View
    83

  • Download
    10

Embed Size (px)

Citation preview

Page 1: Advanced KM Development

Advanced PATROL Knowledge ModuleDevelopment

BMC Software

9 September 2001

Page 2: Advanced KM Development
Page 3: Advanced KM Development

Preface

About this book

This book has been written for developers who have already writtenPATROL Knowledge Modules.

This book is based on papers written by Geert De Peuter and DavidSpuler and the DevCon team’s experience in developing KMs.

To get the most out of this book you should have installed PATROLand understand KM loading, Agent configuration and the basics of thePATROL Architecture.

You need to be casually familiar with the PSL language and canwrite a KM with minimal reference to the PSL reference as no expla-nation of PSL syntax or specific functions are covered. You will wantto have a copy of the PSL Reference Guide handy as you read the codeexamples and work on the exercises.

Hopefully you have taken the Basic PSL development class offeredby BMC Software and read PSL scripts and understand what they aredoing.

If you have developed applications in another language and are fa-miliar with the techniques of good software design, performance tuning,debugging techniques and optimization then this book will help you toapply that knowledge to PATROL Knowledge Module Development.

A quick test of your skill level would be to write a KM that reads theWindows win.ini file and creates an application instance based on eachheading (“[]”) block without or minimal reference to the PSL referencemanual. If you feel you don’t meet any of these descriptions, then thisbook may not be for you. You may want to attend the PATROL admin-istrator’s class and the Basic PSL development class offered by BMCSoftware. Then come back and read this book to take you to a moreadvanced level of KM development.

iii

Page 4: Advanced KM Development

iv Preface

Many of the chapters end with an exercise to help you practice whatyou have just read. If you read at a typical pace, and do all the exercises,you should be able to get through each chapter in 2 to 3 hours, and finishthe book in 40 or 50 hours.

What’s New in this book

As this is a new book, most everything in it is new. However in thisbook we focus on a few key topics that are not found in any publicationon PATROL. In this book we will provide in depth coverage of the PA-TROL Virtual Machine, introduce you to a model to KM development,and offer you key information to enhance the performance of your KMs.In addition, we have tried to make this book as complete as possible byincluding the latest information about PATROL1.

Finally, we added information on several non documented or scarcelydocumented features of PSL and the agent.

How this book is organized

We wanted you to be able to find your way around this book more easily,so we’ve broken this edition up into smaller, more coherent chapters.Here is how the book is laid out:

Chapter 1. Introduction

PATROL is an autonomous agent technology that operates muchlike a virtual machine. In this chapter we’ll describe the autono-mous nature of the PATROL Agent and in a later chapter diveinto the details of the PATROL Virtual machine. This introduc-tion chapter will refresh your knowledge about PATROL when youhave been away from it for a while.

Chapter 2. PSL Language and design

PSL is a powerful language, but why did BMC need to develop yetanother language. This chapter explains a bit about the philoso-phy of the language and gives an introduction to KM development.

KM Development can be broken down many ways. For this docu-ment we have chosen to divide KM development into three phases.

1At the time of publication PATROL 3.5 is about to be released

Page 5: Advanced KM Development

v

This chapter will describe these phases. Later sections and chap-ters will dive into the details of each phase.

Chapter 3. PATROL Virtual Machine

In this chapter we will dive into the internals of the PATROL vir-tual machine. Like other virtual machines, the PATROL Agentoffers internal scheduling, memory control and process execution.We’ll discover each of these aspects of the virtual machine in detailto gain a better understanding of how KMs operate.

Chapter 4. KM Design

This section will drill into the key design decisions you face as youtry to define your KM. This chapter will present you with severalmethods to help prevent KM design pitfalls resulting in better andfaster KM development. We’ll look at performance and which ar-eas of a KM will yield the highest performance gains. We’ll coverportability issue to ensure your KM runs on as many versions ofthe PATROL Agent and Agent platform as possible and concludewith techniques and tools to support internationalization of yourKM.

Chapter 5. Optimizing PSL

This chapter covers more details on how to get more done in PSLwithout spending a lot of CPU cycles.

Chapter 6. Prediscovery and Discovery

prediscovery and discovery are the basis of what a KM does. Thischapter focuses on how to write better discovery scripts and intro-duces you to the notion that you can write more intelligent dis-covery statements. You will also be exposed to some of the moredifficult design decisions as a result of what you learn about dis-covery.

Chapter 7. Instances

The PATROL object tree offers a limited number of levels. Thissimple model is maintained through the use of nested instances.In this chapter you will learn how to create nested instances andtheir effects on the object space as well as some design issues youwill want to consider as you use them.

Page 6: Advanced KM Development

vi Preface

Chapter 8. Parameters and Recovery actions

In this chapter we will cover both the basics of parameters andhow you can use standard parameter types as an enhanced collec-tor. We’ll cover a special parameter that allows you to distributesfiles via PATROL and conclude with some general guidelines onparameter usage.

This section will also provide a few brief comments about how PA-TROL stores history, how you can control history collect and a fewpointers about annotations.

One of the more difficult aspects of KM development is recoverycommands, not because they are difficult to write but because theyrequire knowledge about the application and what effects it. We’llshow you how escalation works and the types of commands avail-able to you.

Chapter 9. Menu Commands and Infoboxes

You can execute commands both at the agent and the console.This chapter will introduces two statements that restrict wheremenu commands can be used. We’ll show you how to extend theALL COMPUTERS class with additional menu items.

Adding to the principles you learn about info boxes, simple briefPSL statements to tell the user basic information about your KM.

Chapter 10. PSL Response Function

If you require user information or action in your KM, communi-cating with the user via the PSL response function is the way toget it done. We’ll introduce you to a tool to make this much easieras well as cover how you handle the list based output of this PSLfunction.

Chapter 11. Using Libraries

Libraries promote code reuse and can be more efficient for memoryusage. This chapter will define what a PSL library is and is not.We’ll show you how to create one and how to next them. Finallythis chapter will conclude with some debugging tips for librariesand some common mistakes you can avoid.

This section concludes with an explaination how PSL binaries canbe used

Page 7: Advanced KM Development

vii

Chapter 12. Configuration Variables

We’ll look at config or environment variables, how to use them andhow they are set. We’ll also discuss when to use them.

Chapter 13. Command Types

You can extend the type of commands PATROL uses beyond OSand PSL. In this chapter you’ll learn how to define command typesand how to use their macros.

Chapter 14. Working with channels

One of the ways to improve performance is the use of channels tocommunication with processes running on the system. This chap-ter will explain how channels to these processes can be createdand used in PSL.

Chapter 15. Events and state change actions

PATROL offers event generation and recovery actions. In thischapter we’ll review agent generated events versus KM generatedevents and finish off with extending event through custom eventcatalogs.

Chapter 16. PATROL and SNMP

PATROL can act both as a SNMP master agent and as a manageddevice (snmp agent). This chapter provides a brief overview of us-age of PATROL in an SNMP environment. It will be followed witha more detailed explanation of how to walk the PATROL names-pace and extracting information from the PATROL tables.

Where to get more information or to make com-ments

Much of the information you read in this book is derived for our web siteat http://devcon.bmc.com At the site you will find documentation, codesamples, SDKs and other content to help you develop PATROL KMs.

Also visit our forums2 for a more interactive experience. You canread what question others have asked as well as post your question.

2http://devcon.bmc.com:8080/∼BMCSOFTWAREDEVELOPERCONNECTION

Page 8: Advanced KM Development

viii Preface

The DevCon team and other members are constantly watching these fo-rums and will try to make sure your development questions are properlyanswered.

We have tested and verified all the information in this book to thebest of our ability, but you may find that features have changed or wemay have made a mistake. Please let us know about any errors you find,as well as your suggestions for future editions, by sending us a messageelectronically. You can ask technical questions or comment on the bookby sending email to mailto:devcon patrol [email protected].

Page 9: Advanced KM Development

Table Of Contents

Preface iii

1 Introduction 191.1 Autonomous Agents . . . . . . . . . . . . . . . . . . . . . . 201.2 Know your territory . . . . . . . . . . . . . . . . . . . . . . 201.3 Think Big ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

1.3.1 More isn’t always better . . . . . . . . . . . . . . . 211.3.2 Nesting or overnesting ? . . . . . . . . . . . . . . . 221.3.3 Look for the exception . . . . . . . . . . . . . . . . 221.3.4 Use all your knowledge . . . . . . . . . . . . . . . . 23

1.4 Think as a customer . . . . . . . . . . . . . . . . . . . . . . 23

2 PSL language and design 252.1 Why (yet) another language ? . . . . . . . . . . . . . . . . . 262.2 Datatypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

2.2.1 Comparisons . . . . . . . . . . . . . . . . . . . . . . 272.2.2 Escape Characters . . . . . . . . . . . . . . . . . . 272.2.3 Special /clearText character sequence . . . . . . . 28

2.3 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292.4 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292.5 Standalone interpreter . . . . . . . . . . . . . . . . . . . . . 302.6 Endless Loop detection . . . . . . . . . . . . . . . . . . . . . 302.7 Storing PSL in KM or seperate file . . . . . . . . . . . . . . 312.8 An approach to KM Development. . . . . . . . . . . . . . . 33

2.8.1 Phase 1 Features . . . . . . . . . . . . . . . . . . . 332.8.2 Phase 2 Features . . . . . . . . . . . . . . . . . . . 342.8.3 Phase 3 Features . . . . . . . . . . . . . . . . . . . 34

1

Page 10: Advanced KM Development

2 TABLE OF CONTENTS

3 The PATROL Virtual Machine 353.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

3.1.1 What is a Virtual Machine? . . . . . . . . . . . . . 363.1.2 Advantages of a VM . . . . . . . . . . . . . . . . . . 37

3.2 The PATROL Virtual Machine . . . . . . . . . . . . . . . . 393.2.1 PSL Code Life Cycle . . . . . . . . . . . . . . . . . 40

3.3 The PATROL Virtual Machine Scheduler . . . . . . . . . . 413.3.1 The Main Loop . . . . . . . . . . . . . . . . . . . . . 423.3.2 Main Run-Queue . . . . . . . . . . . . . . . . . . . 43

3.4 Tuning the Scheduler . . . . . . . . . . . . . . . . . . . . . 433.4.1 RUNQ Scheduler Attributes . . . . . . . . . . . . . 433.4.2 RUNQ Schedule Optimal . . . . . . . . . . . . . . . 453.4.3 Examples for Optimimal Schedule . . . . . . . . . 463.4.4 RUNQ Schedule Force Delta . . . . . . . . . . . . . 493.4.5 Initial RUNQ Scheduling . . . . . . . . . . . . . . . 493.4.6 Normal RUNQ Scheduling . . . . . . . . . . . . . . 50

3.5 Scheduling a PSL process . . . . . . . . . . . . . . . . . . . 523.6 Executing a PSL Process . . . . . . . . . . . . . . . . . . . 533.7 Scheduling an OS Process . . . . . . . . . . . . . . . . . . . 553.8 Executing OS Commands . . . . . . . . . . . . . . . . . . . 55

3.8.1 One-Time Commands . . . . . . . . . . . . . . . . . 563.8.2 Execute vs. System . . . . . . . . . . . . . . . . . . 563.8.3 Connection-Oriented Functions . . . . . . . . . . . 593.8.4 Sharing a channel . . . . . . . . . . . . . . . . . . . 623.8.5 Concurrency . . . . . . . . . . . . . . . . . . . . . . 63

3.9 Global Variables . . . . . . . . . . . . . . . . . . . . . . . . 643.9.1 Nonpermanent Variables . . . . . . . . . . . . . . . 653.9.2 Permanent Variables . . . . . . . . . . . . . . . . . 66

3.10 Local Variables . . . . . . . . . . . . . . . . . . . . . . . . . 663.10.1 Named Variables . . . . . . . . . . . . . . . . . . . 673.10.2 Unnamed Variables . . . . . . . . . . . . . . . . . . 68

3.11 Where Variables are Stored . . . . . . . . . . . . . . . . . . 683.11.1 browsing the namespace . . . . . . . . . . . . . . . 693.11.2 Namespace and attributes . . . . . . . . . . . . . . 703.11.3 Context of a PSL process . . . . . . . . . . . . . . . 71

3.12 Executing inside and outside the VM. . . . . . . . . . . . . 72

Page 11: Advanced KM Development

TABLE OF CONTENTS 3

4 KM Design 754.1 What should a KM Do . . . . . . . . . . . . . . . . . . . . . 75

4.1.1 Better productivity . . . . . . . . . . . . . . . . . . 764.1.2 Get all info about application . . . . . . . . . . . . 764.1.3 Definition of a good KM . . . . . . . . . . . . . . . . 76

4.2 General Guidelines . . . . . . . . . . . . . . . . . . . . . . . 794.2.1 Non-intrusive Application Management . . . . . . 794.2.2 Finding Data Sources . . . . . . . . . . . . . . . . . 804.2.3 Extending Existing KMs . . . . . . . . . . . . . . . 81

4.3 Portable KM design . . . . . . . . . . . . . . . . . . . . . . 834.3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . 834.3.2 Portable agent functionality . . . . . . . . . . . . . 844.3.3 Portability Issues at the Interface with the OS . . 844.3.4 Portable Areas of PSL . . . . . . . . . . . . . . . . 844.3.5 Non-Portable Areas of PSL . . . . . . . . . . . . . . 85

4.4 Portability examples . . . . . . . . . . . . . . . . . . . . . . 864.4.1 Carriage Return Characters (NT, VMS) . . . . . . 874.4.2 process() function (all platforms) . . . . . . . . . . 894.4.3 Launching Child Processes (all platforms) . . . . . 904.4.4 Child Process Error Handling (all platforms) . . . 914.4.5 Preventing Command Failure . . . . . . . . . . . . 914.4.6 Child Process popen() Pipes . . . . . . . . . . . . . 914.4.7 Launching Daemon Processes (all platforms) . . . 92

4.5 Options to Avoid in KM Development . . . . . . . . . . . . 934.6 KM Tracing and Logging . . . . . . . . . . . . . . . . . . . 95

5 Optimizing PSL 975.1 Measuring Performance . . . . . . . . . . . . . . . . . . . . 98

5.1.1 Standalone compiler/interpreter . . . . . . . . . . 985.1.2 Agent Command Line option . . . . . . . . . . . . 995.1.3 From PSL . . . . . . . . . . . . . . . . . . . . . . . . 995.1.4 Profiler KM . . . . . . . . . . . . . . . . . . . . . . . 101

5.2 PSL optimizer . . . . . . . . . . . . . . . . . . . . . . . . . . 1015.3 Architecture Optimization . . . . . . . . . . . . . . . . . . . 108

5.3.1 Frequency of execution . . . . . . . . . . . . . . . . 1085.3.2 Amount of scheduled processes . . . . . . . . . . . 1085.3.3 Amount of spawned processes . . . . . . . . . . . . 108

5.4 PSL Optimization . . . . . . . . . . . . . . . . . . . . . . . 1085.4.1 = , grep() or index() . . . . . . . . . . . . . . . . . . 1085.4.2 multi-string grepping . . . . . . . . . . . . . . . . . 109

Page 12: Advanced KM Development

4 TABLE OF CONTENTS

5.4.3 PSL readln() limitation . . . . . . . . . . . . . . . . 1105.4.4 Evaluation shortcircuiting . . . . . . . . . . . . . . 1115.4.5 Optimize Loops . . . . . . . . . . . . . . . . . . . . 112

5.5 Performance not influenced by ... . . . . . . . . . . . . . . . 112

6 Prediscovery and Discovery 1136.1 History of Prediscovery and Discovery . . . . . . . . . . . . 1136.2 The Discovery Cycle . . . . . . . . . . . . . . . . . . . . . . 114

6.2.1 Prediscovery Or Discovery ? . . . . . . . . . . . . . 1146.2.2 Discovery and Prediscovery Processes . . . . . . . 1166.2.3 Coding Style . . . . . . . . . . . . . . . . . . . . . . 1176.2.4 Full and Partial Discovery . . . . . . . . . . . . . . 1176.2.5 Unique Features of Discovery . . . . . . . . . . . . 119

6.3 Discovery Pitfalls . . . . . . . . . . . . . . . . . . . . . . . . 1206.3.1 Prediscovery and Discovery running together . . . 1206.3.2 Active determines what to execute . . . . . . . . . 121

7 Instances 1237.1 Why you need to create instances . . . . . . . . . . . . . . 1237.2 The Create Function . . . . . . . . . . . . . . . . . . . . . . 1247.3 The Destroy Function . . . . . . . . . . . . . . . . . . . . . 1267.4 Techniques for creating instances . . . . . . . . . . . . . . 128

7.4.1 Classic Create Loop . . . . . . . . . . . . . . . . . . 1287.4.2 Classic Destruction Loop . . . . . . . . . . . . . . . 1297.4.3 Optimizing the Create process . . . . . . . . . . . . 1307.4.4 Create Return Code Checking . . . . . . . . . . . 1317.4.5 File Check . . . . . . . . . . . . . . . . . . . . . . . 1347.4.6 Process Check . . . . . . . . . . . . . . . . . . . . . 135

7.5 Create Icon for class . . . . . . . . . . . . . . . . . . . . . . 1357.6 Nested Instances . . . . . . . . . . . . . . . . . . . . . . . . 137

7.6.1 Main Map Instances . . . . . . . . . . . . . . . . . 1387.6.2 Dummy application class instances . . . . . . . . . 1397.6.3 Determining the parent . . . . . . . . . . . . . . . 139

7.7 Limiting the Number of Instances . . . . . . . . . . . . . . 1397.8 Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . 1417.9 Instance creation pitfalls . . . . . . . . . . . . . . . . . . . 141

7.9.1 Limit number of nesting levels . . . . . . . . . . . 1417.9.2 Characters you should not use . . . . . . . . . . . . 141

7.10 Creating invisible instances . . . . . . . . . . . . . . . . . . 1427.11 Instance filtering . . . . . . . . . . . . . . . . . . . . . . . . 142

Page 13: Advanced KM Development

TABLE OF CONTENTS 5

7.11.1 Adding Instance Filtering by Using Filterlist . . . 1427.11.2 Filtering Suggestions . . . . . . . . . . . . . . . . . 1447.11.3 Condition X . . . . . . . . . . . . . . . . . . . . . . . 1447.11.4 Show only NOT OK instances . . . . . . . . . . . . 1447.11.5 Remove instead of filter . . . . . . . . . . . . . . . 1447.11.6 Allow a configurable limit . . . . . . . . . . . . . . 145

7.12 Instance Pittfalls . . . . . . . . . . . . . . . . . . . . . . . . 1457.12.1 Transient instance/history problem . . . . . . . . . 145

8 Parameters and Recovery Actions 1498.1 Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . 149

8.1.1 Standard Parameters . . . . . . . . . . . . . . . . . 1528.1.2 Consumer . . . . . . . . . . . . . . . . . . . . . . . . 1538.1.3 Collector . . . . . . . . . . . . . . . . . . . . . . . . 155

8.2 Parameter Styles . . . . . . . . . . . . . . . . . . . . . . . . 1558.2.1 Text Parameters . . . . . . . . . . . . . . . . . . . 1558.2.2 No Output Parameters . . . . . . . . . . . . . . . . 1578.2.3 Gauge Parameters . . . . . . . . . . . . . . . . . . 1588.2.4 Graph Parameters . . . . . . . . . . . . . . . . . . . 1598.2.5 State Boolean Parameters . . . . . . . . . . . . . . 1608.2.6 Stoplight Parameters . . . . . . . . . . . . . . . . . 161

8.3 ExtraFilesList Parameter . . . . . . . . . . . . . . . . . . . 1628.3.1 Creating an ExtraFilesList Parameter . . . . . . . 162

8.4 Parameter History . . . . . . . . . . . . . . . . . . . . . . . 1638.5 Annotated Datapoints . . . . . . . . . . . . . . . . . . . . . 1638.6 Alarm Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . 164

8.6.1 Settings . . . . . . . . . . . . . . . . . . . . . . . . . 1658.6.2 Range Overlapping . . . . . . . . . . . . . . . . . . 167

8.7 Recovery Actions . . . . . . . . . . . . . . . . . . . . . . . . 1678.7.1 Use Recovery Actions Intelligently . . . . . . . . . 1688.7.2 Recovery Actions on Alarm1, Alarm2, and Border 1698.7.3 Can Be Used to Tune or Detune . . . . . . . . . . . 1698.7.4 Debugging Recovery Actions . . . . . . . . . . . . . 169

8.8 Pitfalls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1698.8.1 Turn History Off If Not Needed . . . . . . . . . . . 1698.8.2 Set Scheduling to a Reasonable Interval . . . . . . 1708.8.3 Value attribute . . . . . . . . . . . . . . . . . . . . . 170

Page 14: Advanced KM Development

6 TABLE OF CONTENTS

9 Menu Commands and Infoboxes 1719.1 Menu Commands . . . . . . . . . . . . . . . . . . . . . . . . 1719.2 Menu command pragma’s . . . . . . . . . . . . . . . . . . . 171

9.2.1 Developer Console Only Commands . . . . . . . . 1719.2.2 Console side menu commands . . . . . . . . . . . . 1729.2.3 %%{. . . } macro . . . . . . . . . . . . . . . . . . . . 172

9.3 Command or Task execution . . . . . . . . . . . . . . . . . 1739.3.1 Command . . . . . . . . . . . . . . . . . . . . . . . . 1739.3.2 Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . 174

9.4 Extending Computer Class Menu Commands . . . . . . . 1749.5 Infoboxes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1759.6 Menu Commands and Infoboxes Pitfalls . . . . . . . . . . 177

9.6.1 Limit the script size . . . . . . . . . . . . . . . . . . 1779.6.2 Delay in showing task output window . . . . . . . 177

10 PSL Response Function 17910.1 Response Function . . . . . . . . . . . . . . . . . . . . . . . 179

10.1.1 Response Function Control . . . . . . . . . . . . . . 17910.1.2 Response() Return Value . . . . . . . . . . . . . . . 179

10.2 Dynamic Response Functions . . . . . . . . . . . . . . . . . 18110.3 Response Pitfalls . . . . . . . . . . . . . . . . . . . . . . . . 181

10.3.1 Ensuring only a single active response . . . . . . . 18110.3.2 Clicker behaviour . . . . . . . . . . . . . . . . . . . 184

11 PSL Libraries 18711.1 What PSL Libraries Are . . . . . . . . . . . . . . . . . . . . 18711.2 How the Agent loads libraries . . . . . . . . . . . . . . . . 18811.3 How to Use PSL Libraries . . . . . . . . . . . . . . . . . . . 190

11.3.1 Requires . . . . . . . . . . . . . . . . . . . . . . . . 19011.3.2 Export . . . . . . . . . . . . . . . . . . . . . . . . . . 191

11.4 Exporting Variables . . . . . . . . . . . . . . . . . . . . . . 19211.5 Exporting Functions . . . . . . . . . . . . . . . . . . . . . . 193

11.5.1 Code Sharing . . . . . . . . . . . . . . . . . . . . . . 19311.5.2 Code Reuse . . . . . . . . . . . . . . . . . . . . . . . 19311.5.3 Function Variables . . . . . . . . . . . . . . . . . . 19311.5.4 Function Hiding . . . . . . . . . . . . . . . . . . . . 194

11.6 Creating PSL Libraries . . . . . . . . . . . . . . . . . . . . 19511.7 Nested PSL Libraries . . . . . . . . . . . . . . . . . . . . . 196

11.7.1 Cyclical Dependencies of PSL Libraries . . . . . . 19711.7.2 Three or More Levels of Libraries . . . . . . . . . . 197

Page 15: Advanced KM Development

TABLE OF CONTENTS 7

11.8 Statically Linked PSL Libraries . . . . . . . . . . . . . . . 19711.9 Performance Issues of PSL Libraries . . . . . . . . . . . . 19711.10Debugging PSL Libraries . . . . . . . . . . . . . . . . . . . 198

11.10.1 Solution to Debugging PSL Libraries . . . . . . . . 19811.10.2 Changing PSL Libraries . . . . . . . . . . . . . . . 19811.10.3 Loading New PSL Libraries . . . . . . . . . . . . . 19811.10.4 Commit Does Not Work for Libraries . . . . . . . . 199

11.11Problems with Nesting . . . . . . . . . . . . . . . . . . . . . 19911.12How to Change PSL Libraries . . . . . . . . . . . . . . . . 199

11.12.1 %DUMP LIBRARIES . . . . . . . . . . . . . . . . . 20211.12.2 Library Difference Checking . . . . . . . . . . . . . 202

11.13Determining Library Dependencies . . . . . . . . . . . . . 20211.14Library Type . . . . . . . . . . . . . . . . . . . . . . . . . . 20411.15PSL Binaries . . . . . . . . . . . . . . . . . . . . . . . . . . 20411.16Pitfalls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20411.17Limitations of PSL Libraries . . . . . . . . . . . . . . . . . 204

11.17.1 Libraries Must Be Present at Compile Time . . . . 20611.17.2 The Console Doesn’t Distribute Libraries . . . . . 20611.17.3 Prediscovery Will Fail . . . . . . . . . . . . . . . . . 206

12 Configuration Variables 20912.1 PATROL Agent Initialization Process . . . . . . . . . . . . 20912.2 Text Configfile Format . . . . . . . . . . . . . . . . . . . . . 20912.3 Config File actions . . . . . . . . . . . . . . . . . . . . . . . 21112.4 Useful configuration variables for development . . . . . . 21512.5 Security Settings in the Agent . . . . . . . . . . . . . . . . 215

12.5.1 defaultAccount . . . . . . . . . . . . . . . . . . . . . 21512.5.2 OSdefaultAccount . . . . . . . . . . . . . . . . . . . 21612.5.3 OSdefaultAccountAppliesToCmds . . . . . . . . . . 21612.5.4 Determining Security Context (for %{username}

and %{password}) . . . . . . . . . . . . . . . . . . . 217

13 Command Types 21913.1 Command Types . . . . . . . . . . . . . . . . . . . . . . . . 21913.2 Command Type Features . . . . . . . . . . . . . . . . . . . 22113.3 Command Type Macros . . . . . . . . . . . . . . . . . . . . 222

13.3.1 Using the %{command} Macro . . . . . . . . . . . 22513.3.2 Not Using the %{command} Macro . . . . . . . . 22613.3.3 Using the %{commandFile} Macro . . . . . . . . . 229

13.4 Command Types and UNIX Shell Issues . . . . . . . . . . 230

Page 16: Advanced KM Development

8 TABLE OF CONTENTS

13.5 Command Types in (pre)discovery . . . . . . . . . . . . . . 231

14 Global Channels 23314.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 233

14.1.1 Global Channels . . . . . . . . . . . . . . . . . . . . 23314.1.2 Shared Channel Locking . . . . . . . . . . . . . . . 234

14.2 Channel Example . . . . . . . . . . . . . . . . . . . . . . . . 23514.3 Channel Pitfalls . . . . . . . . . . . . . . . . . . . . . . . . . 237

14.3.1 Shared channels not closed . . . . . . . . . . . . . 23714.3.2 Channel synchronization . . . . . . . . . . . . . . . 238

15 Events and state change actions 24115.1 Introduction to event . . . . . . . . . . . . . . . . . . . . . . 241

15.1.1 Agent generated events . . . . . . . . . . . . . . . . 24115.1.2 KM generated events . . . . . . . . . . . . . . . . . 242

15.2 Event Catalogs . . . . . . . . . . . . . . . . . . . . . . . . . 24315.2.1 Custom Event Catalog . . . . . . . . . . . . . . . . 24315.2.2 Elements of an Event Class Dialog . . . . . . . . . 24315.2.3 State Change Actions . . . . . . . . . . . . . . . . . 245

15.3 PatrolCli PSL execute . . . . . . . . . . . . . . . . . . . . . 246

16 PATROL and SNMP 24916.1 SNMP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249

16.1.1 Master Agent . . . . . . . . . . . . . . . . . . . . . 24916.1.2 Sending Traps . . . . . . . . . . . . . . . . . . . . . 25016.1.3 SNMP Trap sending . . . . . . . . . . . . . . . . . 251

16.2 SNMP Pitfalls . . . . . . . . . . . . . . . . . . . . . . . . . . 25216.2.1 support for SNMPv2 . . . . . . . . . . . . . . . . . 252

A PSL Internal function 253A.1 Windows NT PSL internal function . . . . . . . . . . . . . 253

A.1.1 NT GetRegistryValue . . . . . . . . . . . . . . . . . 254A.1.2 NT GetRegistrySubkeys . . . . . . . . . . . . . . . 256A.1.3 NT PerfObjectExists . . . . . . . . . . . . . . . . . 257A.1.4 NT DiskPerfEnabled . . . . . . . . . . . . . . . . . 257A.1.5 NT GetPerformanceValue . . . . . . . . . . . . . . 258A.1.6 NT GetPerformanceValue Counter Format Details 260A.1.7 NT CalcPerformanceValue . . . . . . . . . . . . . . 261A.1.8 NT GetUserRegszKeyValue . . . . . . . . . . . . . 262

A.2 Compatibility of NT Internal Commands . . . . . . . . . . 262

Page 17: Advanced KM Development

TABLE OF CONTENTS 9

A.3 UNIX PSL internal function . . . . . . . . . . . . . . . . . 262A.4 VMS internal function . . . . . . . . . . . . . . . . . . . . . 264

A.4.1 VMS GetProcessCache . . . . . . . . . . . . . . . . 264A.4.2 VMS GetProcessInfo . . . . . . . . . . . . . . . . . 265A.4.3 VMS GetQueueInfo . . . . . . . . . . . . . . . . . . 265A.4.4 VMS GetSystemInfo . . . . . . . . . . . . . . . . . 266

B (Micro-)Optimizing your code 269B.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 269B.2 First Optimization . . . . . . . . . . . . . . . . . . . . . . . 270B.3 Prevent looping . . . . . . . . . . . . . . . . . . . . . . . . . 271B.4 Micro Optimization . . . . . . . . . . . . . . . . . . . . . . . 272B.5 Another problem . . . . . . . . . . . . . . . . . . . . . . . . 272B.6 Aren’t One-liners even faster ? . . . . . . . . . . . . . . . . 273B.7 Don’t trust everything you copy and paste . . . . . . . . . 274

Page 18: Advanced KM Development

10 TABLE OF CONTENTS

Page 19: Advanced KM Development

List of Tables

13.1 Command type properties . . . . . . . . . . . . . . . . . . . 22113.2 Macro’s in command types . . . . . . . . . . . . . . . . . . . 223

15.1 Macro’s in state change actions . . . . . . . . . . . . . . . . 246

11

Page 20: Advanced KM Development

12 LIST OF TABLES

Page 21: Advanced KM Development

Listings

4.1 Portable cat() function tabsize . . . . . . . . . . . . . . . . . 884.2 Example of ported system functions tabsize . . . . . . . . . 906.1 Safely checking existence of a library tabsize . . . . . . . . 1156.2 Checking for file updates in discovery tabsize . . . . . . . . 1187.1 Typical create loop tabsize . . . . . . . . . . . . . . . . . . . 1287.2 Typical destruction loop tabsize . . . . . . . . . . . . . . . . 1297.3 Optimizing discovery tabsize . . . . . . . . . . . . . . . . . 1307.4 Problem when not checking return code of create tabsize . 1317.5 With create return code checking tabsize . . . . . . . . . . 1327.6 Alternative to checking each return code tabsize . . . . . . 1337.7 With File Check tabsize . . . . . . . . . . . . . . . . . . . . 1347.8 Checking for process cache updates tabsize . . . . . . . . . 1357.9 Changing the filterlist from PSL tabsize . . . . . . . . . . . 14316.1 Simple SNMP traps in PSL tabsize . . . . . . . . . . . . . . 25116.2 Another SNMP trap script tabsize . . . . . . . . . . . . . . 251

13

Page 22: Advanced KM Development

14 LISTINGS

Page 23: Advanced KM Development

List of Slides

1.1 KM development introduction . . . . . . . . . . . . . . . . . 192.1 PSL language fundamentals . . . . . . . . . . . . . . . . . . 252.2 An approach to KM Development . . . . . . . . . . . . . . . 333.1 Virtual Machine Basics . . . . . . . . . . . . . . . . . . . . . 353.2 The Java VM . . . . . . . . . . . . . . . . . . . . . . . . . . . 373.3 Advantages of a VM . . . . . . . . . . . . . . . . . . . . . . . 383.4 The PATROL Virtual Machine . . . . . . . . . . . . . . . . . 393.5 PSL Code life cycle . . . . . . . . . . . . . . . . . . . . . . . 403.6 Scheduler Components . . . . . . . . . . . . . . . . . . . . . 423.7 The RUNQ Scheduler Attributes . . . . . . . . . . . . . . . 443.8 Algorithm to calculate optimal RUNQ schedule . . . . . . . 463.9 Schedule Optimal : Example 1 . . . . . . . . . . . . . . . . 473.10 Schedule Optimal : Example 2 . . . . . . . . . . . . . . . . 473.11 Schedule Optimal : Example 3 . . . . . . . . . . . . . . . . 483.12 Schedule Optimal : Example 4 . . . . . . . . . . . . . . . . 483.13 Force RUNQ Delta . . . . . . . . . . . . . . . . . . . . . . . 493.14 Initial RUNQ Scheduling . . . . . . . . . . . . . . . . . . . . 503.15 Normal RUNQ Scheduling . . . . . . . . . . . . . . . . . . . 513.16 Scheduling a PSL process . . . . . . . . . . . . . . . . . . . 523.17 Executing a PSL process . . . . . . . . . . . . . . . . . . . . 533.18 Scheduling an OS process . . . . . . . . . . . . . . . . . . . 553.19 One-Time Commands . . . . . . . . . . . . . . . . . . . . . . 563.20 Executing a system command . . . . . . . . . . . . . . . . . 583.21 Executing an execute command . . . . . . . . . . . . . . . . 593.22 Connection Oriented Functions . . . . . . . . . . . . . . . . 603.23 What happens when you execute popen() . . . . . . . . . . 613.24 What happens when you execute fopen() . . . . . . . . . . . 623.25 Sharing a process channel . . . . . . . . . . . . . . . . . . . 633.26 Solving concurrency through locking . . . . . . . . . . . . . 643.27 Global Variables . . . . . . . . . . . . . . . . . . . . . . . . . 65

15

Page 24: Advanced KM Development

16 LIST OF SLIDES

3.28 Local Variables . . . . . . . . . . . . . . . . . . . . . . . . . 673.29 Where are variables stored . . . . . . . . . . . . . . . . . . . 693.30 Attributes in the PATROL namespace . . . . . . . . . . . . 713.31 Context of a PSL process . . . . . . . . . . . . . . . . . . . . 723.32 Execute Inside or Outside the VM ? . . . . . . . . . . . . . . 734.1 Expected functionality of a KM . . . . . . . . . . . . . . . . 754.2 General Guidelines for KM development . . . . . . . . . . . 794.3 Finding Data Sources . . . . . . . . . . . . . . . . . . . . . . 804.4 Extending Existing KM’s . . . . . . . . . . . . . . . . . . . . 824.5 KM Portability . . . . . . . . . . . . . . . . . . . . . . . . . . 834.6 Non-Portable Area’s of PSL . . . . . . . . . . . . . . . . . . 854.7 Examples of Portability Problems . . . . . . . . . . . . . . . 864.8 Options to Avoid in KM Development . . . . . . . . . . . . 935.1 PSL Profiling . . . . . . . . . . . . . . . . . . . . . . . . . . . 985.2 Activating the PSL Profiler . . . . . . . . . . . . . . . . . . 995.3 Using the PSL Profiler Functions . . . . . . . . . . . . . . . 1005.4 Profiler Output . . . . . . . . . . . . . . . . . . . . . . . . . 1005.5 Introduction to the PSL Optimizer . . . . . . . . . . . . . . 1015.6 Levels of Optimization . . . . . . . . . . . . . . . . . . . . . 1025.7 Level 1 Remove Useless Jumps . . . . . . . . . . . . . . . . 1025.8 Level 1 Reduce Jump Chains . . . . . . . . . . . . . . . . . 1035.9 Level 1 Remove Redundant Quad . . . . . . . . . . . . . . . 1035.10 Level 1 Pack Parameters . . . . . . . . . . . . . . . . . . . . 1045.11 Level 2 String joining . . . . . . . . . . . . . . . . . . . . . . 1045.12 Level 2 Fold and propagate . . . . . . . . . . . . . . . . . . 1055.13 Level 2 Remove Multiple and unused Definitions . . . . . . 1055.14 Level 2 Reorder Parameters . . . . . . . . . . . . . . . . . . 1065.15 Level 3 Remove Unreachable code . . . . . . . . . . . . . . 1065.16 Level 3 Reduce Block Chains . . . . . . . . . . . . . . . . . 1075.17 Optimizer and Menu Commands . . . . . . . . . . . . . . . 1075.18 Expression Short-Circuiting . . . . . . . . . . . . . . . . . . 1115.19 Loop Optimizations . . . . . . . . . . . . . . . . . . . . . . . 1126.1 Prediscovery and Discovery process . . . . . . . . . . . . . . 1146.2 Discovery Cycle . . . . . . . . . . . . . . . . . . . . . . . . . 1166.3 Unique Features of Discovery . . . . . . . . . . . . . . . . . 1196.4 Discovery Pitfalls . . . . . . . . . . . . . . . . . . . . . . . . 1207.1 Instance Creation . . . . . . . . . . . . . . . . . . . . . . . . 1257.2 Instance destruction . . . . . . . . . . . . . . . . . . . . . . 1277.3 Nested Instances without icon for class . . . . . . . . . . . 1367.4 Example for create Icon for class . . . . . . . . . . . . . . . 136

Page 25: Advanced KM Development

LIST OF SLIDES 17

7.5 Create syntax for nested instances . . . . . . . . . . . . . . 1377.6 Nested Instances creation (icon for class) . . . . . . . . . . 1388.1 Different Parameter Types . . . . . . . . . . . . . . . . . . . 1528.2 Standard Parameter . . . . . . . . . . . . . . . . . . . . . . 1538.3 Consumer parameter . . . . . . . . . . . . . . . . . . . . . . 1548.4 Collector parameter . . . . . . . . . . . . . . . . . . . . . . . 1558.5 Text Parameters . . . . . . . . . . . . . . . . . . . . . . . . . 1568.6 No Output Parameters . . . . . . . . . . . . . . . . . . . . . 1578.7 Gauge Parameters . . . . . . . . . . . . . . . . . . . . . . . . 1588.8 Graph Parameters . . . . . . . . . . . . . . . . . . . . . . . . 1598.9 State Boolean Parameters . . . . . . . . . . . . . . . . . . . 1608.10 Stoplight pre V3.4 . . . . . . . . . . . . . . . . . . . . . . . . 1618.11 Stoplight post V3.4 . . . . . . . . . . . . . . . . . . . . . . . 1628.12 Annotated Datapoints . . . . . . . . . . . . . . . . . . . . . 1648.13 Alarm Range settings . . . . . . . . . . . . . . . . . . . . . . 1668.14 Range Overlapping . . . . . . . . . . . . . . . . . . . . . . . 1678.15 Intelligent Recovery Actions . . . . . . . . . . . . . . . . . . 1688.16 Pitfalls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1709.1 Menu Command Pragma’s . . . . . . . . . . . . . . . . . . . 1729.2 Menu Command : Execute as a command . . . . . . . . . . 1739.3 Menu Command : Execute as a task . . . . . . . . . . . . . 1749.4 Infobox commands . . . . . . . . . . . . . . . . . . . . . . . 17611.1 What are PSL libraries ? . . . . . . . . . . . . . . . . . . . . 18811.2 How the Agent loads libraries . . . . . . . . . . . . . . . . . 18911.3 How to Use PSL Libraries . . . . . . . . . . . . . . . . . . . 19011.4 Exporting Variables . . . . . . . . . . . . . . . . . . . . . . . 19311.5 Exporting functions . . . . . . . . . . . . . . . . . . . . . . . 19411.6 Creating PSL libraries . . . . . . . . . . . . . . . . . . . . . 19511.7 Nested PSL libraries . . . . . . . . . . . . . . . . . . . . . . 19611.8 Changing PSL libraries I . . . . . . . . . . . . . . . . . . . . 20111.9 Changing PSL Libraries II . . . . . . . . . . . . . . . . . . . 20111.10Changing PSL Libraries III . . . . . . . . . . . . . . . . . . 20211.11Determining PSL library Dependencies . . . . . . . . . . . 20311.12Limitations of PSL libraries . . . . . . . . . . . . . . . . . . 20511.13Library Pitfalls . . . . . . . . . . . . . . . . . . . . . . . . . 20712.1 Format of the ASCII configuration file . . . . . . . . . . . . 21012.2 Syntax of a configuration variable . . . . . . . . . . . . . . 21112.3 Syntax of the configuration actions . . . . . . . . . . . . . . 21212.4 Syntax of the configuration value . . . . . . . . . . . . . . . 21212.5 Modifying the Binary Configuration File I . . . . . . . . . . 213

Page 26: Advanced KM Development

18 LIST OF SLIDES

12.6 Modifying the Binary Configuration File II . . . . . . . . . 21312.7 Modifying the Binary Configuration File III . . . . . . . . . 21412.8 Useful Configuration Variables for Development . . . . . . 21512.9 Security Settings in the Agent . . . . . . . . . . . . . . . . . 21613.1 How Command Types Are Created . . . . . . . . . . . . . . 22013.2 Why Use Command Types . . . . . . . . . . . . . . . . . . . 22013.3 Command type Features . . . . . . . . . . . . . . . . . . . . 22213.4 Command Type Macro’s . . . . . . . . . . . . . . . . . . . . 22413.5 Using the command macro . . . . . . . . . . . . . . . . . . . 22513.6 Not using command or commandfile . . . . . . . . . . . . . 22713.7 Using the commandFile macro . . . . . . . . . . . . . . . . 230

Page 27: Advanced KM Development

Chapter 1

Introduction

�������������� ��������������������! #" $&%��'�(��)*�+�-,����intelligent��.��/�&01�����/�2%43657�(57�8����9&��37%�:��(�����8�<;=%�:��+�2%>;�%����

����,�57��)?.�57 @@ ScalabilityScalability@@ ACBEDGFEHJILKNM�KNFNO-HQPSRUTACBVD+FVHQILK=M&K=FWO-HQPQR7T@@ NestingNesting@@ X'YNZEY=[ HJDGH Z R�FV\]HQ^=PSHQ_VRU`aK ZX'Y=ZEYN[ HJD+H Z R&FE\bHQ^NPQHS_�R7`cK Z@@ d KNB Y IQHLR7eVH8HQ^=_EHJISR�fd K=B Y IQH8RUeEHLHQ^N_EHJIQR�f

����,�57��)?�&�b�>;����<�2%&�(���

Slide 1.1: KM development introduction

19

Page 28: Advanced KM Development

20 Introduction

1.1 Autonomous Agents

The PATROL architecture is built on the the idea of autonomous agents.Autonomous means the agents should be able to run at all times, with-out any consoles or other clients connectedt. The execution engine ofthe agent also allows for a lot of automation, ensuring that the oper-ators have more time to work on the problems that really need theirattention without having to take care of all the problems.

In order to accomplish this, the agent will have to be programmed tobe intelligent. When you install and run an agent out of the box, it won’treally do a lot (actually it will just sit there and wait until you tell it orconfigure it to do something). The way to make PATROL agents moreintelligent is by writing knowledge modules. When the PATROL admin-istrator loads the KM, the agent will start executing the code defined init.

This book will not explain how to install, start or configure the agent,how KM loading or the PATROL user interface works, but we will haveto define some areas before we can get started. It is important to knowas a developer, what you are allowed to do with an agent and what thejob is of the operator or administrator.

1.2 Know your territory

Some KM developers tend to get a little bit too overactive when they aredeveloping a KM. This is usually caused by the power of the PSL lan-guage. Although this language is used for KM development, it shouldbe clear that there are parts in the agent you shouldn’t modify.

All the agent tuning parameters are stored in pconfig (the PATROLconfiguration database) and a developer has access to this data. Oneof the common mistakes is the idea some developers have on tuningthe agent. It is important that your KM doesn’t modify variables thatinfluence the agents operation. For example a KM should never auto-matically modify the /AgentSetup/preloadedKMs value to enforce per-sistency. A KM should also leave the agent’s tuning variable alone andleave the job of changing these values up the PATROL administrator.

The reason for this is that these configuration setting will influ-ence more than just the operation of your KM, but they can change theagent’s impact on the system completely.

Page 29: Advanced KM Development

1.3 Think Big ! 21

1.3 Think Big !

Some developers write code as if their development machine in their de-velopment environment is representative of all the systems that wouldever run his code. This could potentially lead to problems in the arena ofscalability, performance and usability. Although your development ma-chine might look ”average” to you, the code you will develop on it willprobably run on system much bigger and much smaller than yours. Ifyou write a KM to monitor a specific application (for example a webserver), are you aware that some people might actually run 100 in-stances of this application ? Would these people still be interested inall the detailed information you would provide for this single webserver? Maybe they would like to be able to toggle between overview moni-toring mode and detailed monitoring ? What would happen if someoneinstalls that KM on a computer of 3 years ago, let’s say a P100 with64Mb memory ?

As you can see it is important to think in extremes and your shouldnever consider your system as an average system, because a customerwith a P100 will definitely consider that to be an average system.

Also think carefully how far you should go with optimization. A KMthat can potentially be installed on a large amount of systems should betuned as much as possible. Let’s say you can squeeze 1 percent of CPUof the overall CPU consumption of your KM. If a someone runs thatKM on 1000 systems, this 1% saving will be multiplied by 1000 systems(about 10 computers).

1.3.1 More isn’t always better

One of the powers of PSL is the ease to extend current functionality. Youshould determine the level of detail you want to present before actuallywriting it. Most developers don’t have a problem not writing something,but hate the idea of removing something they already wrote. When adeveloper starts writing a KM, usually the application is researched formetrics that could be exposed. After a list of metrics is compiled, thedeveloper will verify if these metrics make sense. The proper way to dothis is by asking someone close to the application which parameters onecould be interested in. This becomes the basic functionality for the KM.Often the developer will present the list of parameters and ask whichones are really not needed. This approach is the same as walking witha kid in a candy store and then asking the child for the items the kid

Page 30: Advanced KM Development

22 Introduction

wouldn’t like to have. . . you will probably end up buying a lot more thanif you would have asked the question what candy you should bring whenyou go to the candy store.

It even gets worse if the developer hasn’t properly researched theapplication and just starts writing code from the user or API documen-tation. The amount of data presented in the KM will be huge, but thevalue or information probably minimal. It is the task of the developerto be as creative as possible to turn this data into information withoutover using code cycles, CPU cycles or memory.

1.3.2 Nesting or overnesting ?

PATROL allows for nesting of instances. Although this GUI featurecan make the representation of information more structured, it can alsomake it a big effort for an operator to find the information he is lookingfor. One of the warning sign of too deep nesting is probably if you arenesting more than 6 levels deep, if your design nests this deep, youmight want to consider restructuring your information, because it mightbe hard for an operator to find the needed information. It might makemore sense to just remove some of the KM that are nested so deeply andreplace the information with menu commands that will generated whenthe user needs it.

1.3.3 Look for the exception

Before you consider yourself ready to start coding, imagine the situationwhere everything on every server goes into alarm. Do you create addi-tional instances when something is in alarm (for example an instancefor every log entry) ? Would it still make sense to show all that info ?

Will your KM spawn a response functions to warn someone in a cer-tain case (let’s say application is switched to maintenance mode) ? Howwould you feel if you see behind a terminal and suddenly all your 1000computers go into alarm because your application was in that mode ?

While you are going through all the potential failure situations, alsocheck for the all-OK case. Do you have any instances that no one willever look at or need reporting data for while everything is going well ?Maybe you shouldn’t create the instance unconditionally.

Page 31: Advanced KM Development

1.4 Think as a customer 23

1.3.4 Use all your knowledge

One of the most effective ways to prevent the Christmas tree effect (allinstances turning red) in your KM would simply be to define no alarmsat all on any of the parameters and leave it all up to the customer. Butwhy do you think the customer will ever buy KMs ? Usually because itshows intelligent, specific knowledge about the application and becausethey feel quite confident that they will be notified of problems. So ifyou never implemented alarms or intelligence in your KM, you are notdelivering to the customer what they expect and you will not sell manyKMs (you might even never pass the part of the sales cycle). Againresearch will be important. When you decide to implement a certainmetric as a parameter, always ask yourself if the value of this parameteris always good (usually parameters for reporting) or if there are anyexceptions you should take into account.

For example, you are writing a KM to monitor hardware and one ofthe values indicates the ”internal temperature”. When you write yourKM, you see the value of that parameter is 70◦C. The next thing youshould do is look in the manual for ”operating temperatures” and setthe maximum and possibly minimum values. If you can’t find this inthe manual, then you should call the support office of that applicationto find out what the nominal values are. Remember, if you don’t do it,the customer will eventually have to do it and they will probably notvalue the KM very high.

After you defined these alarm ranges, you should see if there arerecovery actions you can take. Most people will require a toggle on anyrecovery actions you provide (default=off, for demos you want all bellsand whistles enabled). An example recovery action would be to turn thespeed of the hardware momentarily down, so it can cool a bit. You shouldnever forget that you have to be able to recovery from a recovery actionand return to normal operation after the temperature has dropped.

1.4 Think as a customer

Before you go off and start coding you should take two steps (or more)back and spend at least an hour thinking as a customer. Draw yourdesign on a piece of paper and imagine the code already written. Thiswill help you prevent usability errors that could seriously impact theKM and it’s design. For every instance you create think what the userwould expect to find underneath. Check if it makes sense to create all

Page 32: Advanced KM Development

24 Introduction

the parameters and see if the location of the menu commands makesense.

A customer is usually not interested to see if you can do it, but ismore interested in how well you can do it.

Page 33: Advanced KM Development

Chapter 2

PSL language and design

g�hi,�$4j�$�����k8�&��%&��,�����36���� ��l�� ��+mnn o�p=q�rbs7tbuavQpNwQxoypNq�rbs7tbucvSp=wSxnn zC{Q{SvQq�q�sUt]q-|EpNwQvQ}/}Ep=s7pb~UwQtN���G�Eucs7�c�EucvL�EwQtN{QvQq�q�vQqzC{Q{QvSq-q�s7tbq�|Ep=wSvQ}+}EpNsUp]~�wSt=���G�EuasU�a�VuavL�EwQt={SvQq�q�vJqnn Interpreted/portableInterpreted/portableg���&�� &���� �� datatype � ��9��=��$���,l57�l 456�b���<����56�� nn � �+�VpN{Js�t=x/{Qt��+�Ep=wQ�aq�t=x� �G�EpN{Js&tNx+{St��G�EpNwQ�cq�tNxnn VariablesVariablesg�������;���5U%&��� � ;���373� �$�9&�&3U�l�

g�������������37%��l�+57���-�=��:����=�-���

Slide 2.1: PSL language fundamentals

This chapter provides an overview of the PSL language by going overdesign decisions. As mentioned before, we expect you to know mostof the PSL functions that are available. In case you are not acquainted

25

Page 34: Advanced KM Development

26 PSL language and design

with the functions yet, you will probably need the PSL reference manualto do some additional research on the basics of the PSL function.

2.1 Why (yet) another language ?

In the first versions of PATROL, there was no scripting language. Themonitoring features of the product were all builtin and there was hardlyany way to customize it. Before any of these versions of PATROL werereleased on the market, it became obvious that the flexibility of theproduct was very much limited because of the lack of a scripting lan-guage. When defining the design of the language, the following itemswere considered top priority

• Easy to learn

• Need for access to shared data. From within one script, one shouldbe able to access data collected by another script.

• Easily execute on any OS by means of interpretation

• The interpreter should support ”multiple” scripts running at thesame time, without the use of multiple threads

• A badly written script should not bring down all the other scripts

• Functions for communication with OS and execution of OS com-mands.

• Fast enough with a small impact on the OS.

One of the frequently asked questions is : “why didn’t you chooseperl, python, calm, scheme, C, java, ... as the ’native’ language for theagent ?”. The reason is simple. Neither of these languages will conformwith the goals that were set in the design. Therefore it seemed likethere was a need for yet another language and BMC called it PSL.

2.2 Datatypes

In order to make it easier to learn the language, it was decided to stayaway from explicit data types and the string datatype was chosen asthe datatype. This has some implications, because some functions or

Page 35: Advanced KM Development

2.2 Datatypes 27

operators require or work with integer or float values. For these func-tions, the input strings will be converted to the needed datatype for theoperation and after the operation completes, stored again as a string.

The function or operator will decide how the input should be cast.For example, bitwise instructions (such as shift left), need two integervalues and the bitwise operator will take care of the conversion. Anoperation like +, -, x, / will work with double precision (like almost allthe other arithmetic operations).

2.2.1 Comparisons

Since all this happens under the hood, you as a developer should nor-mally not be aware that the internal datatype is actually a string andthe PSL language will usually work the way you expect it to work. How-ever the moment you should be aware how everything is stored is whenyou want to compare to variables.

PSL will try to decide which type of comparison is necessary whenyou type :

if ( a == b ) {...}If a and b can be evaluated to numbers, the interpreter will do an nu-merical comparison. If one of them is not a number then a string com-parison is used. In some special cases this can lead to confusion. Let’spresume the PSL comparison :

if (! a ) { a = "EMPTY"; }If you really want to test for a non-empty string then this code mightnot do what you expect it to do. If a="00000000"; then this is con-sidered a valid number and therefore the test if (!0) { a = "EMPTY"; }will succeed although the string is not empty. To force non-empty stringcomparison, one should do the following :

if ( a == "") { a = "EMPTY"; }Which is a true empty string comparison. If you want to compare acertain null-prefixed number as a string you can do so by insuring thenumber is evaluated as a string like this :

if ("X".a == "X0001") { ... }

2.2.2 Escape Characters

Inside a string you can specify some escape characters by preceding aregular character with a ’\’. These escaped characters will be recognized

Page 36: Advanced KM Development

28 PSL language and design

at compile/parse time of your PSL script, that means, even before thestring is stored internally.

There are only a few string literals supported :

\t tab\n new-line\r return\b backspace\A..\Z Ctrl-A ... Ctrl-Z\\ escaped backslash\" escaped quote

The control characters can be very useful if you want to serializedata stored in a PSL variable (for example before storing them in aconfiguration variable). For example :

# Serialize variable for storage in pconfig()# Replace all comma’s with \Cser myvar=replace(myvar,",","\C");# Now store the variablepconfig("APPEND","/MYKM/myvar",ser myvar);

When you read the variables, you could easily undo the serializationas a workaround of the comma delimiter which is hardcoded in pconfiglists.

2.2.3 Special /clearText character sequence

The text parameter and system output window are a kind of a terminalwindow, and recognize a limited number of escape sequences. Actuallythe only escape sequence that will be properly handled are ”clearscreen”character sequences for ANSI and VT100 terminals (Esc [H Esc 2J andEsc [;H Esc 2J). Sending this sequence will clear the window.

Sequences to change the color, appearance, or any other VT100 ter-minal sequences will not be recognized. When you do a :

print(get("/clearText"));you will print the ANSI terminal clearscreen escape sequence and thisis recognized by the text output window.

Just to show you, type the following in a system output window :%PSL printf("%c[H%c[2J",27,27);

And you will see the screen will clear as well.

Page 37: Advanced KM Development

2.3 Variables 29

2.3 Variables

Before a variable is used in PSL, the interpreter will make sure thevariable is initialized before it is used. All variables are automaticallyinitialized to the empty string “”. Although the PSL manual sometimesmentions that a certain function will return NULL, this is actuallyan impossible return value in PATROL. A variable can never containNULL. The best PSL can do is an empty string.

Some people wonder if there is a limitation to the datasize one canstore in a variable. This size is limited to the memory the interpretercan get from the OS. Memory allocation for variables is dynamic andwill automatically be released upon termination of the process.

Since the storage of variables is a string, you will not be able to store0 (null-byte characters). The interpreter will see a null-byte as a stringterminator. This is something you have to be aware of when you arereading binary data from a file that can contain null-bytes.

For every PSL process, 3 variables will be automatically defined.These are exit status, errno and PslDebug. We will explain these inlater chapters.

2.4 Functions

When calling functions, you will pass a copy of the value to the func-tion (also known as call by value). There is only one exception to this,the PslExecute(); function will actually modify the arguments of thefunction. A function that returns data will always return a copy of thedata.

For each function one can define a set of local variables. The numberof local variables is limited to 20 per function.

If a main() function is defined then this main function is consideredthe starting point of execution. That means that all loose code1 will beignored. If your loose code contains initializations then they will not beexecuted. This usually results in a lot of confusion and misunderstand-ing.

A good coding style is to always have a main() function for everydecent size PSL script. Don’t forget to add your initialization routine tothe main function in that case.

1code between functions

Page 38: Advanced KM Development

30 PSL language and design

2.5 Standalone interpreter

Some people don’t realize that the PSL language can be used outside ofthe PATROL agent as well. Whenever you install an agent, you will seea standalone psl compiler and interpreter. This interpreter has a coupleof limitations you should be aware of :

• Can only run 1 PSL process at the same time

• No access to the namespace

• Some commands not available : popen, execute, system, snmp*,pconfig

2.6 Endless Loop detection

The are two configuration variable that determine when the agent con-siders a process to be in an infinite loop :

• pslInstructionMax

• pslInstructionPeriod

pslInstructionMax and pslInstructionPeriod work together. If a PSLprocess executes more than pslInstructionMax PSL instructions withinpslInstructionPeriod seconds, the PSL process incurs internal schedul-ing delay. So both variables define the total PSL instructions a PSLprocess can execute without the delay.

The pslInstructionPeriod is a global timer for the agent. That meansevery pslInstructionPeriod seconds, all instructioncounters for all PSLprocesses that haven’t reached pslInstructionMax yet, will be reset tozero. However, if your process has reached pslInstructionMax already,it will not be reset, and the instructioncounter will just continue to in-crease for that PSL process.

When a process will be detuned, the agent will calculate the lengthof the delay in function of the total number of instructions, compared tothe setting of Instruction Max.

Once a process gets on the ”blacklist”, it will not be removed again,so you should make sure you don’t end up on that list. In case youhave seen that one of your PSL process executes more than allowed ona typical agent, you have to find out if the logic of your process can’t bechanged, so it won’t execute so much PSL functions.

Page 39: Advanced KM Development

2.7 Storing PSL in KM or seperate file 31

Before your program starts executing, the agent will not know if itcontains an endless loop, but the agent will determine this at runtime,because the instruction count was to high over the period of time. Aninstruction is any QUAD instruction. For example (ntharg(), cat(), ...)but also calls to user defined functions. Actually it is counting the num-ber of virtual machine instructions, ”executed” by the VM instructionset processor. (More about VM’s later)

To find out how many instructions are executed for a certain pslfunction, you can use the stand-alone psl compiler/interpreter :

psl -O3P3 <your psl script>

Then the last line from the output will be :

[program name] [instruction count] quads,[total assigns] assigns

2.7 Storing PSL in KM or seperate file

When you save PSL code in the KM, the KM will contain all knowledgeto manage a certain application. Only the KM file would be needed andno extra PSL scripts have to be shipped. (That is if you don’t requirelibraries as well)

The difference is in the KM file. Normally the KM will either containthe PSL script itself or a pointer to where the PSL script can be found.If the PSL is part of the KM, the COMMAND TEXT attribute for aparameter, menu command ,infobox or (pre)discovery in a KM file wouldlook something like this :

BASE_COMMAND = {{ COMPUTER_TYPE = "ALL_COMPUTERS", COMMAND_TYPE = "PSL",COMMAND_TEXT = 852329761 "phome = get(\"/patrolHome\");\hname = get(\"/hostname\");\portno = get(\"/udpPort\");\mach = get(\"/appType\");\[snip]set(\"value\",int(siz));"}

Otherwise it would contain the LOAD statement like shown here :

Page 40: Advanced KM Development

32 PSL language and design

BASE_COMMAND = {{ COMPUTER_TYPE = "ALL_COMPUTERS", COMMAND_TYPE = "PSL",COMMAND_TEXT = LOAD "usr_proc_collector.psl"}},

When you want to write a patch for a certain KM, and the PSL isnot inside the KM file, you can just replace the exisiting psl file witha newer one. Any other PSL files that haven’t changed would not beaffected. Also, the file sizes for each of the files will be very small andin some cases that’s a good thing when doing small upgrades/changes.But the customer would need all files to be there before a KM would befunctional, more files can mean more administration on his side... ormore work if he wants to repackage your KM.

Another benefit of having it in a separate psl file, is if you are usingCVS or similar source control mechanism. The granularity for checkingin files will be smaller and it’s easier to track changes on specific files.Besides that, when PSL is stored in an external file, you can just open itwith a text editor and copy/paste or even read the code without havingto deal with escaped quotes, newlines and such.

If all PSL is part of a KM, and you want to bring out a newer ver-sion of your KM, you only have to ship one file, no matter how muchyou changed. However, by shipping a new KM file, you might overwritechanges made to any other script inside the KM. I mean if the KM con-tains all PSL and if someone wrote additional parameters in the KM,or changed some code in one of the parameters, you will automaticallyoverwrite that if you replace the old KM with a new KM file. The benefitof storing everything inside the KM is that you don’t have to determinedependencies and find out which files have to be shipped as well. Onlythe KM file will do.

Page 41: Advanced KM Development

2.8 An approach to KM Development. 33

2.8 An approach to KM Development.

�����<���7�����

DiscoveryDiscovery�� �<���7�����U���U�U���� ¢¡ ������£¤��¥§¦2�7��<���7�����7�����7���� ¢¡¨���U�/£¤��¥§¦2�7��� © �7¥§ª¬«¢­2�����2¥�®¯�© �U¥§ª¬«¢­2���¬�2¥¯®��

�����<���7��°��

InfoBoxInfoBox�� £¢�U±7­2²��U�7³� ¢±7��´¨­�¥§�£¢�7±7­2²����7³V ¢±U��´¨­µ¥����

PortingPorting�����<���7��¶�� «¢­2�����2¥¯®�·=³2¸��7�«¢­2�����2¥�®¬·N³2¸¯�7���

ChannelsChannels��LibrariesLibraries�� ¹ ¥§¡¨´¨¥���º��U¡¨¸¬��»¢�¼�7��®�­�±�ª����U¥��½���½´¨­�¥¹ ¥�¡ ´¨¥¯��º&�7¡¾¸¬��»¢�¼�7��®�­�±Uª¯���U¥§�¿�µ�¿´¨­µ¥

Slide 2.2: An approach to KM Development

Although there are many other ways to approach KM development, Wewill describe a three-step process for KM development on slide 2.2.

2.8.1 Phase 1 Features

The first step will produce a self sufficient KM and cover the primaryaspects of KM development. In order to create a minimal, though func-tional KM you should develop the following :

Discovery Develop the best way to find the components of the applica-tion and create an icon to represent it.

Parameters Measure specific values about the application, such as itsperformance, capacity, and load metrics.

Page 42: Advanced KM Development

34 PSL language and design

Alarm Ranges Define numeric ranges that specify when a parameterwill go into alarm because the parameter value is in a dangerouscondition.

Menu Commands Develop a minimal set of administrative actionsthat the user can perform from the console in an ad-hoc manner.

2.8.2 Phase 2 Features

The second step, phase 2, will add polish to the KM and provide a com-mercial or production-level KM.

InfoBox commands Define what you should display in the popup re-port available on the console.

Platform support Make sure you check for simple requirements, suchas whether the KM is running on the correct platform agent. Takethe proper action in case a KM is not supported on the platform.

Recovery actions Try to develop actions to correct problems that havebeen found. Verify if you want to have these recovery actions en-abled out of the box. Usually, the KM developer will provide truediagnostic reports and offer options to run corrective actions auto-matically or operator driven.

2.8.3 Phase 3 Features

The third and optional phase covers the harder to understand yet morepowerful features a KM may have.

Command Types Try to avoid the usage of system() commands. Usecommand types instead.

Channels If it makes sense, channels can offer an efficient methodof accessing data that is available through some interactive com-mand such as an application-specific CLI

Libraries Maybe you would like to eliminate duplicate code or groupcommon user PSL functions into one file to be shared by all PSLscripts.

Online help Should be provided for all KMs that will be resold

Page 43: Advanced KM Development

Chapter 3

The PATROL VirtualMachine

3.1 Introduction

ÀÂÁ�5U��������3�ÃÄ��;�,l57���ÅÅ SelfSelf-- ÆSÇ=ÈEÉ7Ê=ËaÈVÌSÍ+ÇNÎVÌSÏQÊ=É7ËaÈEÐ]ÌQÈEÑ=ËaÏQÇ=ÈEÒ+ÌQÈEÉ�É7ÓVÊNÉ&ÊNÆQÉ7Ô�ÕcËcÖEÌLÊÆQÇNÈVÉ7ÊNËcÈEÌQÍ/Ç=ÎEÌQÏQÊNÉ7ËcȤÐbÌSÈVÑNËcÏQÇNÈEÒGÌQÈEÉ&ÉUÓEÊNÉ&ÊNÆQÉ7Ô�ÕaËcÖEÌLÊÔ�ÌQÎEÊ=ÏQÊNÉ7ÌLÆQÇ�Ò+ÎE×VÉUÌQÏÔ�ÌQÎEÊNÏQÊ=É7ÌLÆSÇ�ÒGÎE×EÉ�ÌSÏ

ÅÅ Ø ×EÈEÔ�Ò+×EÕcÉ7ËcÎEÕcÌLÙCËcÏSÉU×EÊNÕÛÚ'Ê=ÆQÓEËcÈEÌLÎEÏQÇNÆQÌQÔ�Ô�ÌSÔØ ×EÈVÔlÒG×EÕcÉ7ËaÎVÕaÌLÙ#ËaÏQÉ7×EÊ=ÕÛÚ'ÊNÆQÓEËcÈEÌLÎEÏQÇ=ÆSÌQÔ�Ô�ÌQÔÅÅ Ü ÈEÍEÌQÏQÔ�É7ÊNÈVÍEÔlÊbÙCËcÏQÉ7×EÊ=Õ�ÚÝÊNÆQÓEËcÈEÌLÞyÊNÈEÐ=×EÊ=ÐNÌÜ ÈEÍVÌSÏQÔ�É7Ê=ÈEÍEÔ�Ê]Ù#ËaÏQÉ7×VÊNÕÛÚ'Ê=ÆSÓVËaÈEÌLÞyÊ=ÈEÐN×VÊNÐ=Ì

ÀÂ�C�ß�à�ßá�Á�à 57�bâ��<:���;�57�&36ãÅÅ ä ÆSÆQÌQÔ�Ô�ÉUÇ]×VÈEÍEÌQÏSÕcå=ËaÈEÐbÓEÇNÔ�É�æ�çä ÆQÆQÌSÔ�Ô�É7Çb×EÈEÍVÌSÏQÕcåNËcÈEÐbÓEÇWÔ�É&æ�çÅÅ ä ÆSÆQÌQÔ�Ôl×EÈVÍEÌQÏLÍEËaè�èUÌQÏQÌSÈVÉ�ÆQÏQÌSÍEÌQÈEÉUËaÊ=ÕaÔä ÆQÆQÌSÔ�Ô�×EÈEÍEÌQÏLÍEËcèUè�ÌSÏQÌQÈEÉ&ÆSÏQÌQÍEÌQÈEÉ7ËcÊNÕcÔ

Slide 3.1: Virtual Machine Basics

35

Page 44: Advanced KM Development

36 The PATROL Virtual Machine

The PATROL agent is a real virtual machine. Although the PATROLagent is only a single process on the host OS, the PATROL agent has itsown scheduler to schedule and execute multiple processes. Each processin the agent has private memory, and has access to the VM’s sharedmemory.

3.1.1 What is a Virtual Machine?

A virtual machine is a self-contained operating environment that be-haves as if it is a seperate computer.

Unlike some virtual machines (like Java), the PATROL VM has fullaccess to the host operating system, with the possibilty to communicateto the host OS under different credentials. Instead of requiring the de-veloper to write and compile executables for each of the different OS’sthe PATROL VM technology allows you to write a single script that willbe compiled and interpreted in a platform independent fashion. Thisapproach makes it easy to run your scripts on any platform on whichthe VM runs.

One of the most well know virtual machines is the Java virtual ma-chine1. As illustrated on slide 3.2, inside the Java VM, java source iscompiled into byte code. In case of a Java applet, this byte code (whichcontains the list Java VM instructions) is then transported over the weband executed by the Java VM (which is running in your web browser).

In case of a Java application, your Java run-time environment willexecute this byte code.

1It is interesting to know that the PATROL VM existed long before the Java VM wasinvented

Page 45: Advanced KM Development

3.1 Introduction 37

éé ê¼ë�ì�í½îEï�ð7ñ�ò ï�ó2ñ7ð�îEô§õ¨ö7ô¬ð7÷¯ø§ê�õ¾ø�ù�ñUú�ñUø�ù�ñ7ø�í�ò óê¼ë�ì�í�îEï�ð7ñ�ò¨ï�ó2ñ7ð=îVô§õ¨ö7ô¬ð7÷¯ø§ê�õ¾ø§ù¯ñUú§ñ�ø§ù¯ñ7ø§í�ò¨óë�ìQí�ô�ñ�êûú§ñ�ö7õ¨ì�õ¨ö�ô§ï2ð7ù§îVïµðUñë�ìQí�ô§ñ�êûú§ñUöUõ ì½õ ö�ô§ï2ðUù§îEï�ð7ñ-- ë�ú�ñUðUï2í�õ¨ø§üë�ú�ñ7ð�ï2í�õ¨ø§ü

systemsystem

éé ðU÷�ø�ê�ë2ø�í½ô�ñ�ö7ò¨õ¨ñ7ø§íð7÷¯ø§ê�ë2ø¬í�ô¯ñ�öUò õ¨ñ7ø�í-- öUë�ø§êû÷Sý¬ñUê�ö7ò¨õ¾ñ7ø§íö�ëµø�êû÷¯ý�ñ7êWö7ò¨õ¨ñUø§í

resourcesresources

éé þ ï�ÿ�ïEï2ú¯ú§ò¨ñ7í������ þ ï�ÿµï��¢ú�ú§ò¨õ¨ö7ï�í�õ¾ë�øþ ï�ÿ�ïEï2ú�ú�ò ñUí������ þ ï�ÿ�ï��¢ú¯ú§ò¨õ öUïµí½õ¾ëµø�¢ø¬ï2ú§ú�ò¾ñ7íQö7ï2ø�ø�ëµíQñ�ñUö7÷§í�ñ�öUò õ¨ñUø�í�� ��¢ø¬ï2ú§ú§ò¾ñUíSöUï�ø¯ø§ë�íQñ�ñ7öU÷§í�ñ�ö7ò¨õ¨ñUø§í�� �öUë2ý�ý�ï2ø�ù�ê��ö7ë2ý�ý�ï2ø¯ù�ê��

����������

����� �� �!#" �code

bytecode

JavaCompiler

Javainterpreter

Slide 3.2: The Java VM

3.1.2 Advantages of a VM

An enormous advantage of this design is that you only need to know oneOS if you want to write virtual machine programs. If you understandhow the VM works, you know how the agent will behave on any hostOS. A KM is just a set of programs that the PATROL agent needs torun (this is a little bit too simplified since a KM contains more than justcommands to execute, but the most important part is is the code).

Although the VM is a self-contained operating environment, with itsown native programming language (PSL), it is possible to use any otherprogramming language within the VM. This is possible because the PA-TROL VM has a very good support for executing host OS commands.The VM on NT even has a javascript and vbscript engine compiled intomake execution of script written in those languages even easier.

Most virtual machines don’t allow the VM to execute host commandsto make sure the machine acts fully self-contained. Since PATROL wasdesigned to gather information of the OS where it is running on, com-

Page 46: Advanced KM Development

38 The PATROL Virtual Machine

municating with the host OS is one of its primary tasks. Actually thePATROL VM is optimized for executing host commands and offers fea-tures like being able to spawn processes with any credentials or openingcommunication channels towards OS processes so the OS process cancontinue to run and has better responsiveness and less performanceimpact on the OS.

$Âá��36$4�������'�2%4)*��%&0%% &�'�(*),+ æ�ç&�'�(*)-+ æ�ç%% &�'�(*),+/.�0�1�2�0�3546487:9�2<;:3�9�2�=�3�2�(&�'�(*)-+>.�0�1�2�0�3�464?7�9�2@;:3�9�2�=�3�2�(ACB ä,&�D æFE ),+>G�3�9IHC;:(�3�0�9KJ53�L�1�=�M 1�M'�(�0*;:3�9�2�=�3�2�(�NPOAQB ä,&�D æFE ),+/G�3�9RHQ;�(�350�9SJ�3�L�1�=�MT1�M'�(�0*;�3�9�2�=�3�2�(�NUO

$�57�(57�����':�%&����57�l 4�5VUV�%&���$XW��!��3637���/:����+:���%&;����J�YV�%�%���:l��57���

$Âhi,�$>��%&���]�C�ß�à�ßá Á�à ,���9��/ZW ��;=;��=�<�]m[[ ç .�(�G�7 è 7:G�3�;�; åY\ 0�7�M]M(�98M1@4?1�9�7:M1�0*3�.�.�;�7:G�3�M7:1�9�NS3�9�^_M]'�( æ�çç .�(�G�7 è 7:G�3�;:; å`\ 0�7:MM(�9_M]1`4?1�9�7�M]1�0*3�.�.�;:7�G�3�M7�1�9�NS3�9�^8M'�( æ�ç

Slide 3.3: Advantages of a VM

If you know PSL you can write programs that will run in every OSwhere the VM runs on without being a master of the OS you execute on.Your skill should be limited to knowing the VM itself. Of course whenexecuting OS commands, you will make your code system dependent.

Page 47: Advanced KM Development

3.2 The PATROL Virtual Machine 39

3.2 The PATROL Virtual Machine

Mem

� �ba<ðc�ö7ñded�� PatrolAgent

fhgei jCk:lnm:o]p�gejCqCrsMemory

ftg:i jCk:lScheduler

uvwu xyz{||}

uvwu xyz{||~

uvwu xyz{||�

Mem Mem

Kernel������� ^

Memory Scheduler

��� �������

��� �������

��� �������

MemoryMemoryMemory

Slide 3.4: The PATROL Virtual Machine

The PATROL Virtual Machine is also known as the PATROL agent. Theagent acts like it is multi-tasking and can run a lot of PSL processes atthe same time. The agent also has a very lightweight mechanism ofswapping PSL processes in and out. Let’s first look at the PSL codelifecycle.

Page 48: Advanced KM Development

40 The PATROL Virtual Machine

3.2.1 PSL Code Life Cycle

"S� ��������]���

���dependant

execOptimized� ����� � �����

PSLCompiler

PSLinterpreter

" �������:� �]�����

�� � �<�T�¯���<�t���� a��¡�¢�£¤¡<�&�¤¥: a���� �<�T�¯�t�<�����¤ c��¡¦¢�£�¡<����¥� c��� a�<� ¢�£�§�¨ª©¬« ���T© �­¨ª« �¤ :¥:£¤�®§ c�<� ¢t£�§�¨ª©¬« �t� © �­¨ª« �¤ :¥�£��®§independentindependent

�� ¯S° ��¡¦¢�£¤¡<��± �#²ª³<� ° �ª �©´§8�¯µ° �¤¡�¢�£¤¡<��± �#²ª³@� ° �ª :©´§8��� ¶ £�§·¨ª©¬« �����<�¯�¶ £�§·¨ª©¬« �t�&�<���£¤¨ª :©´§�©¬¸µ�� :©¬£¤��¨ª£��6��©¬¹ª©¬«¬©¬ :© ���£�¨ª :©´§¦©¬¸��� �©¬£��¦¨ª£¯�6��©¬¹ª©¬«¬©¬ �© ���

� ����� � �����

PSLOptimizer

Slide 3.5: PSL Code life cycle

The code that the PSL compiler generates is the instruction code for thePATROL VM (quad code). The PATROL VM will behave as a VirtualInstruction Set Processor and quad code is the language it understands.

After compilation of the PSL source code, you only have VM instruc-tions left. These instructions are a “smart” translation of your sourcecode into a language that the VM can understand.

Before the VM will execute the code, it should be optimized first (bythe optimizer). The optimizer works on compiled code and tries to turnit into even better code. The optimizer takes a couple of very complexsteps where a smart, but lightweight interpretation takes place. Be-cause the optimizer knows the exact capabilities of the VM execution en-gine, it can reformat/realign your code without changing the logic whileincreasing the effectiveness of your code. We will discuss the optimizerin further detail in a later chapter.

Page 49: Advanced KM Development

3.3 The PATROL Virtual Machine Scheduler 41

After optimization, the compiled PSL code can be saved into a PSLlibrary which is then ready to be used by a PATROL agent without needof further compilation or optimization.

When the agent receives PSL source code that has to be executedmore than once2 the agent will store the compiled PSL in its PSL cache.If you even want to skip that first compilation step, you can pre-compilea parameter script to a .bin file, or you can save the mostly used code ina library. To compile your PSL scripts into bin files you will have to usethe standalone PSL interpreter.

If you are interested to see what these quad instructions look like,then type psl -q to dump the quad code table.

Now that you have an overview of how PSL code flows through theagent, let’s dive into the finer details of how it all works.

3.3 The PATROL Virtual Machine Scheduler

After the code is optimized, a PATROL process is created (rtcell). Thisprocess is then scheduled for execution by passing the process on to therun-queue scheduler (main run-queue). When the time arrives for theprocess to be executed the run-queue scheduler will hand the processto the PSL scheduler to ensure pseudo simultaneous execution by theexecution engine.

The execution engine (also called instruction set processor) is re-sponsible for executing the quad code instructions. Some function thatdo not require host OS access can be handled completely withing theinterpreter. For example, a command like a += 5; is executed inside theVM.

To understand how the PATROL virtual machine works, we willstart by explaining how the scheduling of tasks internally works.

2This is the case for parameters and (pre-)discovery

Page 50: Advanced KM Development

42 The PATROL Virtual Machine

3.3.1 The Main Loop

Mainloop º�»S¼Yº�½�¾#¿ªÀÂÁªÁûĿªÅ5ÀªÆ�Ç5È´Àª½

ÉËÊ­ÌËÍ »�¿ªÅ5ÀªÆ5Ç�È´Àª½

άÏIÐÒÑªÓ Æ�ȬÀª½Ô´ÕªÖ ×ÙØ�ÚªÛªÜ ×¤Ý¬ÚªØ5ÜßÞKàפڪá Úªâ�Ýäã å5â¤àªá á

TimersCleanup

Maintenanceæ�Ø:çªâ¤Úª×�×µèËàªâ¤éªÚ*Ø:ÚªÔ´Ø:ڪפé

Slide 3.6: Scheduler Components

The main loop is the central wait state for the agent and everything theagent does gets initiated from this loop.

Within this loop the agent will perform the following tasks:

Timers The agent has a couple of repetitive tasks and timers will makesure these are executed when they should. Tasks include cleanup/-maintenance (history flush, asynchronous tasks -where its impos-sible to do something straight away-, PSL instruction timer, black-out), Process Cache refresh...

IO Handlers Responsible for maintaining the communication betweenthe agent and the outside world. This subsystem will listen forconsole connections, maintain sessions, and communicate with ex-ternal processes.

RUNQ Scheduler This is the main scheduler for PATROL processes.

Page 51: Advanced KM Development

3.4 Tuning the Scheduler 43

PSL Process Scheduler Responsible for making sure all PSL processesare executed until completed. Also responsible for putting a PSLprocess on an IO wait queue or removing it from the PSL queuewhen it’s done.

3.3.2 Main Run-Queue

The central data structure for the PATROL agent’s scheduling of jobs isthe main run-queue. This is an internal queue data structure that hasall the executable commands, including discovery and pre-discovery, pa-rameters, process cache cycle, menu commands etc. Every PATROL pro-cess that has to be scheduled by the Run-queue scheduler has an rtcellthat contains the runtime information of the process. The main run-queue has jobs that still have to be started, not jobs that are currentlyrunning.

The run-queue is ordered by the time that a command should run.This time is altered only by actions such as Update Parameter other-wise the command will run at the time scheduled.

Commands that should only execute once will not be rescheduled.Discovery and process cache has defined reschedule periods (40 sec &300 sec respectively). These intervals can be changed my modifying theagent’s configuration.

Scheduling is also affected by the agents internal self tuning mea-sures.

A command that has to be executed immediately (i.e. menu com-mand) gets placed at the front of the queue (see slide 3.16).

3.4 Tuning the Scheduler

The RUNQ scheduler is a very important component in the agent. Thebehaviour of the scheduler can be modified by the PATROL adminis-trator and should not be modified by you as a developer. Although youshould not modify these values from within PSL, it’s important to knowhow the scheduler works, since the scheduler is responsible for execut-ing your PSL scripts.

3.4.1 RUNQ Scheduler Attributes

The behavior of the scheduler is defined by a couple of attributes whichare stored inside the pconfig() database.

Page 52: Advanced KM Development

44 The PATROL Virtual Machine

All of the attributes are located under: /AgentSetup/AgentTuningThe different attributes are:

runqDeltarunqDeltaIncrementrunqMaxDeltarunqSchedPolicy

The purpose of these attributes will be explained shortly. For now,note the constraints and defaults these values have.

• Schedule from end and from previous are mutually exclusive andat least one should be specified.

• If both of them are specified, from previous is used, if none of themare specified, from end is used.

• Force delta and optimal are optional and mutually exclusive. Incase both of them are specified, force delta will be used.

ê �5V�5U�����'57�':�;�%��ÙV�5U &j�k`ëíì AgentSetup/AgentTuningîî ��ï�ð�ñ�ò-��ó M ���ï�ð�ñ�ò,��ó M � ACôTõIö N � G�÷ ð ^�OACô�õXö N � G�÷ ð ^�O^ �Qè]��ï�ó MTø@N � G�÷ ð ^�N^ �Sè���ï�ó M ø`N � G�÷ ð ^�Nîî runqDeltaIncrementrunqDeltaIncrementACô�õXö N � G�÷ ð ^RùûúACôTõIö N � G�÷ ð ^Iùûú

runqDeltarunqDelta))^ �Qè]��ï�ó MTü@N � G�÷ ð ^�N^ �Sè���ï�ó M ü`N � G�÷ ð ^�Nîî runqMaxDeltarunqMaxDeltaAQô�õXö�ý N � G�÷ ð ^�NPOACô�õXö�ý N � G�÷ ð ^�NPO^ �Qè]��ï�ó MTþ ý N � G�÷ ð ^�N^ �Sè���ï�ó M þ ý N � G�÷ ð ^�Nîî runqSchedPolicyrunqSchedPolicyÿÿ ���������J������ �� �����>��������������<������ ��������4�����

ÿÿ � �������J������ �� �������������������<�� �������<������ ������������µ���������<�ÿÿ � �������J������ ��������������� �������<������ ������� ���y��ÿÿ �������J������ �� �����µ���<����a� �������<������ ������������<����c�

!#"ªÝ�"ªàÂá á $&%('�â¤á "ª×¤Ü )¤Ú!#"ªÝ�"ªàÂá á $&%('¤â�á "ª×�Ü )¤Ú

Slide 3.7: The RUNQ Scheduler Attributes

Page 53: Advanced KM Development

3.4 Tuning the Scheduler 45

3.4.2 RUNQ Schedule Optimal

The algorithm to calculate the optimal schedule is quite complex, soinstead of going too deep into details, this overview will help you under-stand it’s operation.

Whenever a new process wants to be scheduled, it will have a pro-posed execution time. This proposed execution time will be incrementedwith steps of runqDeltaIncrement until runqMaxDelta is reached. Anyof these times will be seen as possible execution times.

For each of those possible execution times, the agent will calculatethe “time between executions” and the “standard deviation” for all of thealready scheduled processes. This will return two values per possibleexecution time. The agent will then pick the execution time with thegreatest time between executions as the new best-scheduled time forthis parameter.

The standard deviation is used whenever we have 2 schedule timeswith the same time between executions. The new execution time withthen be the one with the smallest standard deviation. A small standarddeviation is an indication of even (optimal) spreading. In case we wouldhave chosen the execution time with the greatest standard deviation,then this would not indicate optimal spreading but be an indication ofa lot of executions happening close to that time and one or a couple ofexecutions would happen in a relatively long time from the new exectiontime.

Page 54: Advanced KM Development

46 The PATROL Virtual Machine

1.* ��:����`ë�:���%�:�%&�J���Ý�<;=,�������3U�/�257�(�/j���k

2. + 57���'%�:��-57�!��3��<;�,������l3U57�l 4 �$�;��&37;��l36����57�l ,, ä.- �����0/�� M21�3 � L � M \-����ð_�54�� G ï M21:÷ ð Nä6- �����7/�� M81 3 � L � M \Y����ð8�94�� G ï M21�÷ ð N,, ç M ��ð ^ ��� ^8^ � -01 � M81�÷ ðç M ��ð ^ ��� ^_^ � -71 � M21:÷ ðV�%��+ ����201�=���'�&373�:l%&�<�J56 �37�+��:6�]�&���'�&��$>%���,l����<;�,������l37���':��=%&;����<�]0ß,������+��5U��5U��;������(���������' �$�����<; ê ��37��� * �l;������(�����8������573�j��>= runqMaxDeltaky56�reached

3.����)*�+ &�����������<�y��9����=�& &�+ ����201������7?���;����256%����

4.* �';����J�A@���9� &�b�����/�-,l�/�J���!�CB��-��)*�+%�����0�57�2,�<�(�&3U36���<��W��2�&�����&��� ê ��9&57���256%&�Ýj� ��������=�+�<:������&��57�l �k

Slide 3.8: Algorithm to calculate optimal RUNQ schedule

3.4.3 Examples for Optimimal Schedule

The scheduler will take the intervals of the parameters into account.On these slides we have 4 parameters. Each has a different interval.

The delta increment is 2 seconds and the Max Delta is 8 seconds(this is just an example, max Delta should normally be more than 10seconds)

If the process we want to schedule has an interval of 4 seconds, itwould be best to schedule it at t=2 (or t=6)

Note: In case you find this all a bit confusing (and it probably is, be-cause there is no real practical value for this), then remember thatit is very unlikely that a parameter will be executed on schedule.The agent will also try do prevent multiple parameters from exe-cuting at the same time. There is no way as a developer to changethis behaviour and you should therefore never expect that two pa-rameters with the same schedule will execute together.

Page 55: Advanced KM Development

3.4 Tuning the Scheduler 47

DFEFGFHJI�KMLON.PRQASTNVUXW6Y0Z�[]\MSDFEFGFH^IRKMLON.P�Q_STNVUXW6Y0Z�[]\_S

t=0 t=2 t=4 t=6 t=8

`(acb9dfe9g9h dji9k l9a�dcmfmjnpo qrbso t�q�dfk ufvchfwcmx dch q�vjy t5ack�dcz<dct9q9{#|cmc}f~�vc� x dch q�vj{#�fm

�(��� o t9q�dck�ufvchcwcm� | � o t9q�dck�ufvchc|cm�(��� o t9q�dck�ufvchc�cm� w � o t9q�dck�ufvchc�cm

Slide 3.9: Schedule Optimal : Example 1

DFEFGFHJI�KMLON.PRQASTNVUXW6Y0Z�[]\MSDFEFGFH^IRKMLON.P�Q_STNVUXW6Y0Z�[]\_S

t=0 t=2 t=4 t=6 t=8

� o q�b<o t9q�dck�ufvchcwfmx dch qrvjy t9afk�dcz<dct9q9{#|cmc}c~#vc� x dch q�vj{#�fm

�(��� o t9q�dck�ufvchcwcm� | � o t9q�dck�ufvchc|cm�(��� o t9q�dck�ufvchc�cm� w � o t9q�dck�ufvchc�cm

� dcmcq9mcacb5dfe9g9h dce<vcq9qr{�|square square 2̂

t=0 2.45 2.4225t=2 3.95 5.4225t=4 2.45 2.4225t=6 3.95 5.4225t=8 2.45 2.4225

Slide 3.10: Schedule Optimal : Example 2

Page 56: Advanced KM Development

48 The PATROL Virtual Machine

DFEFGFHJI�KML6N6PRQASTNVU�WOY0Z�[]\MSDFEFGFHJI�KML6N6PRQASTNVUXW6Y0Z�[]\MS

t=0 t=2 t=4 t=6 t=8

� o q�b<y t9q�dck�ufvchc�cmx dch qrvjy t9ackTdcz<dct9q9{#|cmc}c~#vc� x dch q�vj{#�fm

�(��� o t9qrdck�ufvchcwcm� | � o t9qrdck�ufvchc|cm�(��� o t9qrdck�ufvchc�cm� w � o t9qrdck�ufvchc�cm

� dfmcq9mcacb5dce9g5h dce<vcq9qr{��square square^2

t=0 3.25 3.2225t=2 4.15 6.2225t=4 3.45 5.2225t=6 2.95 4.2225t=8 4.65 7.2225

Slide 3.11: Schedule Optimal : Example 3

DFEFGFHJI�KML6N6PRQASTNVU�WOY0Z�[]\MSDFEFGFHJI�KML6N6PRQASTNVUXW6Y0Z�[]\MS

t=0 t=2 t=4 t=6 t=8

� o q�b<y t9q�dck�ufvchc�cmx dch qrvjy t9ackTdcz<dct9q9{#|cmc}c~#vc� x dch q�vj{#�fm

�(��� o t9qrdck�ufvchcwcm� | � o t9qrdck�ufvchc|cm�(��� o t9qrdck�ufvchc�cm� w � o t9qrdck�ufvchc�cm

� dfmcq9mcacb5dce9g5h dce<vcq9qr{�wsquare square^2

t=0 3.25 3.2225t=2 4.15 6.2225t=4 4.45 10.0225t=6 3.75 5.0225t=8 3.65 4.0225

Slide 3.12: Schedule Optimal : Example 4

Page 57: Advanced KM Development

3.4 Tuning the Scheduler 49

3.4.4 RUNQ Schedule Force Delta

In case we want to force the delta, a process will only be scheduled incase it would not execute between runqDelta from another process.

After a while this will result in adding the processes at the end ofthe queue with the distance of runqDelta

�ÂÁ�����$��l5U�!:�37�>" �����&��;�,'������5U3���,���5U��������9��&3� ����20 �=���:�����9&56%����b:l��%�;����<�����l�'�������8:���%&;����J�]57�]���y36�����<������<� ê ��37��� !!

���,�56�b;=���' ��/57� �49�����$>36%��� 4�257�!���

Slide 3.13: Force RUNQ Delta

3.4.5 Initial RUNQ Scheduling

If a parameter were never scheduled before, the current time would beused as the proposed schedule time.

To prevent all parameters to execute at the same time, they will allbe “scheduled optimal” (unless force delta was already specified).

Page 58: Advanced KM Development

50 The PATROL Virtual Machine

����;�,�������36������%&� �����Tì�:�����9&56%&����56�b56 ���%&������Â��373�:������&�(���������b���J�â��Q;�,������l37�/%&:���57�(�&36ã>j����C������37��k

%&���%&��;��/���=3U���>j252�8�<:���;�52�257����k

Slide 3.14: Initial RUNQ Scheduling

3.4.6 Normal RUNQ Scheduling

The “fine tuning” of the scheduler will happen after we get a new pro-posed execution time.

This proposed schedule time depends on the setting of the policy. Incase we schedule from end we will add interval to the current time afterthe parameter finishes to execute. (Interval will be forced)

If we schedule from previous, we will take the previous exectime andadd interval to it.

After that the scheduling can be optimized, depending on the settingof the policy. This is an optional step.

Page 59: Advanced KM Development

3.4 Tuning the Scheduler 51

������0 :���%&:�%��<��� �<;�,����l��37�/�25U�!�+����:��������]%�� :�%&365U;=$�� � � ÷7��� ���9�7  ÷ � � ÷���� ���9�0  ÷ � � ÷7��÷ ¡P��£� � ÷0��÷ ¡P�9£ exectimeexectime

õ � ���5�0  ÷ ïp¡õ � ���9�7  ÷  �9¤��9¥9¦2  � ���¤���¥9¦2  � � §  �ðp¦�����5��ó§  :ð¢¦���9����ó�� � � ÷7� ��ð¢£� � ÷�� ��ð¢£proposedproposed exectimeexectime

õ ¥�ï�������ðp¦�¦2  � � §  :ð¢¦���9����óõ ¥�ï�������ð¢¦�¦2  � � §  �ðp¦��������ó�Âá:���56%&����3�j�58¨��<:��=;�52¨25U�=��k�C��%�:�%&�<��� �<;�,�������36�+��57�(�/���7©Û���<�����ª¨�%���� æ � ¦2  � ��󫡬¥�����£�ï�ó  :𢭯®æ � ¦8  � ��󫡬¥����9£�ï�ó� :𢭯® runqMaxDeltarunqMaxDelta ùù runqDeltaIncrrunqDeltaIncr))�� �Ë÷ ��¥��*ò,��ó�¦�°®�Ë÷ �9¥��*ò,��ó ¦]�¯® runqDeltarunqDelta))

Slide 3.15: Normal RUNQ Scheduling

Page 60: Advanced KM Development

52 The PATROL Virtual Machine

3.5 Scheduling a PSL process

Mainloop º�»S¼Yº�½�¾#¿ªÀÂÁªÁûĿªÅ5ÀªÆ�Ç5È´Àª½

ÉÒÊ­ÌËÍ »�¿ªÅ�ÀªÆ5Ç�È´Àª½

άÏRÐËÑªÓ Æ�ȬÀª½Timers

± àªÜQÞ³²j´jµ«¶

RTList æ(·s¸#¹ªØ:çªâ¤Úª×�×

º Ô»¹ªØ�çªâ�Úª× ×<¼Òàª×,ÞPçªÝâ�ç�½<¹ªÜ á ÚªÕ�¾ ÚÂÝÀ¿Pâ¤ç«½Á¹ªÜ á ÚÜ Ýªà­ÞUÕ*פݬçªØ:Ú³¶<ªàªÕâ¤çªÕªÚ*ÜQÞ

rtcell

èÒç­ÞPݬàÂÜQÞP׵ݬéªÚ*á Ü ×¤ÝªçªÔØ Â­ÞªÞPÜQÞ®Û³¹ªØ:çªâ¤Úª×�פڪ×

èËç­ÞPݬàÂÜCÞP×ÙݬéªÚá Ü ×�ݪçªÔÂÜßÞPàªâ�Ý¬Ü Ã Ú

processes

(rtcells)

Slide 3.16: Scheduling a PSL process

When a PSL process is scheduled from the main run-queue and exe-cuted, it is placed on the PSL run-queue. The agent runs multiple PSLprocesses through its interpreter, one at a time.

The run-queue scheduler is responsible for moving the processesfrom the RUNQ (the waiting list) on the rtlist that is the list of run-ning processes

Each executing PSL process is allotted a time slice with a fixed setof low-level compiled instructions (quads).

The PSL interpreter runs the PSL process until its timeslice expires,or it is blocked e.g., system(), execute(), popen() and some forms ofread() and write().

Built-in variable /pslTimeslice can be set to control the number ofquad instructions per timeslice.

When a PSL process is blocked it will not appear on either the main

Page 61: Advanced KM Development

3.6 Executing a PSL Process 53

run-queue or the PSL run-queue. PSL processes that are blocked onfunctions such as locking or shared channels, will not stop the agentfrom executing other PSL processes.

In PATROL you can see these processes by executing %DUMP RUNQand %DUMP RTLIST from the system output window.

If the process that is about to be scheduled is a PSL process, it will bepassed on the PSL process scheduler. This includes compiling the PSLprocess if wasn’t compiled before. In section 3.6 we will discuss whathappens to execute a PSL process.

3.6 Executing a PSL Process

Mainloopº�»K¼`º�½�¾#¿ªÀÂÁªÁûĿªÅ�ÀªÆ5Ç5È´Àª½

ÉËÊ­ÌÒÍ »�¿ªÅ5ÀªÆ�Ç5È´Àª½± àªÜCÞ³²j´�µ«¶

RTList

æ(·Á¸#¹ªØ�çªâ�ڪפ×

æ(·#¸�²j´�µ«¶Timeslice

expires

Enqueue

æ�Ø:çªâ¤Úª×�×µâ¤çC½Á¹ªá ڪݬڪ×Dequeue

sleep()

system,exec

fopen,popen,

snmp

άÏIÐÒÑªÓ Æ5ȬÀ�½Timers

Slide 3.17: Executing a PSL process

The PSL process scheduler is responsible for swapping in and swappingout PSL processes.

Whenever a PSL processes has to be executed, it will be put on the

Page 62: Advanced KM Development

54 The PATROL Virtual Machine

PSL runq (at the end). The PSL process scheduler will always take thefirst process of this runq and then execute until:

• 50 low-level instructions are executed (or to whatever pconfig vari-able “/pslTimeslice” is set)

• PSL process does IO (includes snmp functions, fopen(), popen(),system(), execute())

• PSL process goes to sleep

• PSL process terminates/completes

If the process terminates or completes, the process is passed back tothe main run-queue3.

If a time slice is fully used, then the process is put back to the end ofthe PSL run-queue.

If the process has to wait for IO, it will be passed to the IO handler.The process sit in the “IO wait bucket”. Whenever IO completes, thePSL process will be moved back to the end of the PSL run-queue.

Whenever the process executes a sleep(), a timer will be created.If the timer completes, the process will be moved at the end of the PSLrun-queue. The lock() function is similar. In this case the agent will notbe woken up because a timer expired, but because someone unlocked theresource the lock() is waiting for.

3Only if this is a reoccuring process

Page 63: Advanced KM Development

3.7 Scheduling an OS Process 55

3.7 Scheduling an OS Process

Mainloop º�»K¼`º�½�¾#¿�À�ÁªÁûĿªÅ�ÀªÆ5Ç�ÈßÀª½

ÉËÊ­ÌÒÍ »�¿ªÅ5ÀªÆ�Ç5È´Àª½

άÏIÐÒÑªÓ Æ5ȬÀ�½Timers

± àªÜCÞ³²j´�µ«¶

RTList Ä ·Å¹ªØ�çªâ�ڪפ×èËç­ÞPݬàÂÜCÞP×ÙݬéªÚ·á Ü ×�ݪçªÔØ�­ުޮÜQÞPÛ³¹ªØ�çªâ�ڪפ×�Úª×

èÒç­ÞPݬàÂÜQÞP׵ݬéªÚá Ü ×¤ÝªçªÔÂÜCÞPàªâ¤Ý¬Ü äÚ

processes

(rtcells)

ÆÈǤڪâ�ªݬڳ¹ªØ:çªâ¤Úª×�×É ÞPÕ*Ø�ÚÂÛªÜ ×¤Ý¬ÚªØ5Ô´ÕªÖ ×ÙÜCÞ Ý¬éªÚ

º Ä éªà­ÞPÕÂá ÚªØËʱ ç�äÚ*Ø:ݬâ¤Úªá á ݬç̺ Ä éªà­ÞUÕªá ÚªØ�×

waitlist.

Slide 3.18: Scheduling an OS process

If the process that is scheduled is an OS process, it will be executed onthe OS and the process information will be passed to the IO handlerroutine.

Whenever data is returned the IO handler will take the appropriateaction to return the data to the caller.

3.8 Executing OS Commands

You should understand the way PATROL deals with OS commands be-cause they are used frequently in your KMs to get data from your appli-cation.

A possible way to get data out of your application is through a subprocess execution, and it’s important to understand how this works.

Page 64: Advanced KM Development

56 The PATROL Virtual Machine

3.8.1 One-Time Commands

One way to retrieve data from your application is to start a processthat returns the data each time it is launched. This way is useful forcommands that do not work in a conversational way. PSL offers twofunctions that allow you to do this retrieval:

• execute(CMDTYPE,"cmd") : Spawns CMDTYPE with arguments”cmd”.

• system("cmd") : Spawns the OS command interpreter with exe-cution of ”cmd”.

OneOne--

Í System(“ cmd” )ÎÎ ç¢Ï��7Ð-ðpÑÁÒ���8æ ç�Ó ÷0Ô°Ô �5ð¢Õ�ÖPð¢Ò���9Ï�����Ò]���³ÐO× Ò]�_�9Ø��5Ó�ï¢Ò2× ÷ ð ÷ èçpÏ��0ÐYð¢ÑÁÒ]���Læ çAÓ ÷7Ô¯Ô �5ð¢ÕAÖPðpÒ����Ï����9Ò���³Ð6×�Ò�8��Ø��5Ó�ïpÒ2× ÷ ð ÷ è““ cmdcmd””ÙÙ ÚÜÛ ��Ý>Þ»ß ��àÚÜÛ ��Ý>Þ»ß ��à

/bin//bin/ dûôdûô /usr /local/bin//usr /local/bin/myshellmyshell ..shshá Execute(CMDTYPE,” cmd” );ââ ã Þ<��ä�å<�«æjç_èjéÜê¬� Ú ä�ë�ìc�y��í�î�ï»Ýy�ðå�ìa�«ñã Þ<��ä�å<�«æòçAèòé¢ê�� Ú ä�ë�ìa�y��íËî�ï»Ý��ðå�ìc�«ñ cmdcmd””óó ô ¬õ2ý�ú�ò ñ8öô ¬õ2ý¬ú§ò¨ñ2ö execute(LSCMD,"execute(LSCMD," --al" );al" );÷÷ ø7ù2úðûTü2û(ýÿþðü������������� ���� ������������ ������ø0ù2úðûTü2ûÈý þðü�������� ���������������������� ������lsls --lala

Slide 3.19: One-Time Commands

3.8.2 Execute vs. System

These two commands are almost the same :execute("OS",...) = system();

which one you should use will depend on if a shell is required to executeand if pre- and postcommand processing is desired.

Page 65: Advanced KM Development

3.8 Executing OS Commands 57

The system() command

The system() command will unconditionally spawn an OS commandinterpreter and then pass the arguments to that interpreter.

To illustrate this with an example. Let’s say you call the followingfunction :

system("myprogram.sh");This command spawns the OS command interpreter and passes the ar-gument "myprogram.sh" to the interpreter. When you trace this exe-cution on the OS, you will see that this command will cause the follow-ing to execute on a Unix system :

/bin/sh myprogram.sh

For this example, the system() function is the correct one to usesince "myprog.sh" will contain shell commands and therefore need ashell interpreter to run.

However if we would have done system("ls"); then the shell inter-preter is useless and will just be an extra process that could have beenavoided, because the "ls" command does not need a command inter-preter to run (like any executable).

On slide 3.20 we can see that the (useless) shell process that is cre-ated to execute the ls command.

Page 66: Advanced KM Development

58 The PATROL Virtual Machine

system(“system(“ --la” );la” );

Kernelç���������Õ

Memory Scheduler

��� �������

ls-l

a

/bin

/�� � -la

MemoryMemoryMemory

� �ba�!]c�ö7ñded�� PatrolAgent

ftgei jQk�lnmeopg:jQqCr�sMemory

ftgei jQk�lScheduler

uvwu xyz{||}

uvwu xyz{||~

GD

P_E

xam

ple

Mem Mem Mem

…..

system(“ "�# -la” );

…..

Slide 3.20: Executing a system command

The execute() command

To avoid the extra creation of a shell process you could use the execute()command. On slide 3.21 you can see that execute will directly spawnthe desired process without implicitly calling the OS interpreter. As aresult, execute() will use less OS resources. For this reason, execute()is the preferred method for spawning processes in PSL.

Page 67: Advanced KM Development

3.8 Executing OS Commands 59

execute(LSCMD,“execute(LSCMD,“ --la” );la” );

Kernelç��������9Õ

Memory Scheduler

��� �������

��� �������

ls-l

a

MemoryMemoryMemory

� �ba$!c�ö7ñded�� PatrolAgent

fhgei jCk:lnm:o]p�gejCqCrsMemory

ftg:i jCk:lScheduler

uvwu xyz{||}

uvwu xyz{||~

GD

P_E

xam

ple

Mem Mem Mem

…..

execute(LSCMD,” -la” );

…..

æ&%�ݳÝy��å$'>é�(�Þ<�)+*�,.-0/214365�798template=“ ls”:<;=- >?:<@ #BACA -ED A /6FHG)+@ A - ;=,.I�)+* A IJ@<)LKM- A -EN A IJ@M)

Slide 3.21: Executing an execute command

In order for execute() to work, you will have to define a commandtype which we will discuss in a later chapter. We will also see thatthere are extra features that will make execute() even more attractive.Besides that there are also some limitations to be aware of :

Tokenization : The execute function will only do limited tokenization.

Batch files : You won’t be able to execute batch files without calling aOS command interpreter. In case you want to launch batch filesand have no need for the extra features offered by execute, youmight as well use system().

3.8.3 Connection-Oriented Functions

Another way to get data from an application (and using sub-processexecution) is to use the connection-oriented method (also known as achannel), which allows you to communicate to the executable.

Page 68: Advanced KM Development

60 The PATROL Virtual Machine

ConnectionConnection--

OÂ��37�J%4)l��%&0 �'���=�QP�,���������36�RR popenpopen(CMDTYPE,”(CMDTYPE,” cmdcmd” );” );SS read()read()SS write()wr ite()SS close()close()RR fopenfopen(“ filename” );(“ filename” );SS read()read()SS write()wr ite()SS close()close()SS fseekfseek()()SS ftellftell ()()

Slide 3.22: Connection Oriented Functions

These are functions where a continuous connection between the VMand an external process or file is maintained. Following is a descriptionof the PSL functions that allow you to establish channels

Page 69: Advanced KM Development

3.8 Executing OS Commands 61

popen(CMDTYPE,"cmd") function

popenpopen()()

Kernelç��������9Õ

Memory Scheduler

��� �������

��� �������

��� �������

MemoryMemoryMemory

fhgei jCk:lnm:o]p�gejCqCrsMemory

ftg:i jCk:lScheduler

uvwu xyz{||}

uvwu xyz{||~

uvwu xyz{||�

Mem Mem Mem

chan=popen(FTPCMD,mycmd);

...5�T<*�)<)+- " / " @MN * "CU * ;=IJ* V " -W�X�Y ,.* :<:<IJ)MZ A @.N T+* )<)<- "stdin,stdout

Slide 3.23: What happens when you execute popen()

When popen() is called, the PSL interpreter will create a communica-tion channel between your PSL process and the external process. Thiscommunication channel is returned to you. This channel is private fora PSL process.

When the channel is established, you can use functions to talk tothe executable through the channel or listen to your executable withwrite() or read(). When you want to finish the communication you canuse the close() function to stop the channel. The same function can alsobe used to do proper cleanup and stop the spawned child process.

This possibility can greatly improve the performance of the KM youare writing, especially when the start-up of the child process can requirea lot of CPU.

An example is Oracle’s SQLPLUS, which is a conversational com-

Page 70: Advanced KM Development

62 The PATROL Virtual Machine

mand. Instead of writing select statements on stdin, you write it in thechannel. Instead of reading from stdout, you read from the channel.

fopen("filename") function

fopenfopen()()

Kernelç���������Õ

Memory Scheduler

��� �������

��� �������

��� �������

MemoryMemoryMemory

ftgei jQk�lnmeopg:jQqCr�sMemory

ftgei jQk�lScheduler

uvwu xyz{||}

uvwu xyz{||~

uvwu xyz{||�

Mem Mem Mem

chan=fopen(“ /tmp/myfile” );

...5�T+*�)M)+- " / " @<N * "CU * ;[IJ* V " -Y 3]\[I " -&T+* )+K " -

Slide 3.24: What happens when you execute fopen()

Just like subprocess execution, you can use a similar function calledfopen() to access files. This function will return a channel that is pri-vate to the PSL process that called this function.

With files, you can use the following functions to read, write, reposi-tion, tell current position, and close the channel to the file :

read(), write(), fseek(), ftell (), close()

3.8.4 Sharing a channel

By sharing a channel to a process or a file, you allow other PSL processesto use it. The channel will now be named and known in the namespace.

Page 71: Advanced KM Development

3.8 Executing OS Commands 63

If you want to access the same executable or file from multiple PSLprocesses, it is a good habit to let them all share the channel instead oflaunching multiple OS commands and creating multiple channels.

After creation of a channel, the channel is open for everyone to use.To prevent multiple PSL processes accessing it at the same time, youmight consider writing the channel access functions in a library thatwill do all necessary locking to force command serialization over thechannel.

Below, you will find an example to the share() function.

ShareShare popenpopen

Kernelç��������9Õ

Memory Scheduler

��� �������

��� �������

��� �������

MemoryMemoryMemory

fhgei jCk:lnm:o]p�gejCqCrsMemory

ftg:i jCk:lScheduler

uvwu xyz{||}

uvwu xyz{||~

uvwu xyz{||�

Mem Mem Mem

chan=popen(FTPCMD,prc2cmd);

...

5�T<*�)<)+- " / " @MN * "CU * ;=IJ* V " -W�X�Y ,.* :<:<IJ)MZ A @.N T+* )<)<- "stdin,stdout

share(chan,”mychan”);

^ *�,.- # :M* NE-0N @<) A * IJ) #�# T+* ;[- K.N T<*E)<)+- " )+*�,.-write(“mychan” ,prc3cmd);

Slide 3.25: Sharing a process channel

3.8.5 Concurrency

Since only one PSL process can be in the running at any given time,there are no low-level concurrency problems. Any PSL process can beinterrupted after execution of any statement (this can also happen dur-ing execution of blocking functions that require IO).

Two or more PSL processes that logically share data structures (for

Page 72: Advanced KM Development

64 The PATROL Virtual Machine

example : a variable in the namespace) can be interrupted when halfwaythrough a transaction, leaving the shared data structure in an unde-sired state.

If this is the case, you should identify these transactions and uselock() to make sure that only a single PSL process can access the sharedresource at any given time.

This doesn’t only apply to namespace variables, but also to channels.

_ Chan=(p/f)open(….,….);`` ó ÷ Ó���óÛè ÷ �³Ò���2a¬ç�b Ï�� ÷ Ó���ѬÑó ÷ Ó���óÛè ÷ �>Ò]���2a¬ç�b Ï�� ÷ Ó��9ѬÑ_ Share(chan,” share_name” );`` c ����ð�ð���ó­ð�� Ô �9Õ�×�ð8ð�� Ô �9ѬÏ��7Ó��*��ð¢Õ Ô �7Õ��*��Ó�Ó��9ѬÑc×=d�ó��2dVåc ����ð�ð���ó­ð�� Ô �9ÕA×:ð_ð�� Ô ��ÑcÏ��0Ó��*��ðpÕ Ô �0Õ��*��Ó9Ó��9ѬÑc×=d�ó:�2dEå��ó:ó ÷ Ò]�����2a�ç�b��ó:ó ÷ Ò�����2a¬ç�b Ï�� ÷ Ó���ѬÑP�9ÑÏ�� ÷ Ó��9ѬÑP�9Ñ_ (un)lock(“ share_name” ,…)’`` aË���Ce5��ðpÒ2ÑÁÑ¬× Ô ï�ó�Ò��ð�� ÷ ï¢ÑSïpÑP�4f�� ÷ èòÓ�����ð�ð���óaË���Ce���ð¢Ò2Ñ<Ñ¬× Ô ï�ó�Ò��ð�� ÷ ïpÑSï¢ÑP�gf�� ÷ è�Ó�����ð�ð���ó

Slide 3.26: Solving concurrency through locking

3.9 Global Variables

Global variables are accessible from within any PSL process and havethe following variables associated with them:

Global variables are typically addressed with their PATH definitionin the PATROL agent’s object store (also known as heap). Below is a listof global variable examples:

/ipAddress

Page 73: Advanced KM Development

3.9 Global Variables 65

/MYAPP/myvar/AgentSetup/defaultAccount/ORACLE/instances

h ä Ó�Ó��9ѬѬ×=d�ó��Lè�� ÷7Ô Ð6×�Ò�¢×:ð8��ðEåji¬ç�kliË� ÷ Ó���ѬÑmm NonNon-- Þ<��íðÝ���å<��å�ìÞ<��íðÝy��å<��å�ì-- n �6���«ß ���6�«í2�µ��%�ï�í o��µ�n �6���«ß �µ�7�Cí2���B%�ï�íEo����pp q�c�dsr�õ t�rvuw!�!�udsr õ !wrq�c�d=r9õ t�r�ux!�!wudsr õ !�rpp ô4y õ�z|{+}�u�tv~+�M��r�� c�� dôgy õ�z&{<}�u�t�~+�<�wr�� c�� d�� � �=�����w�=��� �����J���w� �E�[� �|���6� � �� �s�������s��� �����J���x� �E��� �|���6� �E�

myvarmyvar))mm ����íðÝ���å<�ðå�ì�=��íðÝy��å<�ðå�ì-- � � ��ï�ë�í��µ�Û� Û ì�í��sí��µ��%�ï�í o��µ�� �E��ï�ë�í����Û� Û ì�íµ�sí����B%�ï�íEo����pp a$u�!wz�õ��Mu��+rC�Äc �+t�����~<!8õErv� c��a$u�!xz�õ��<u��<r���cE�<t�����~<!2õ r�� c���� �����v���=��  ¡���v�����s��  ¡

configconfig--databasedatabase�� ¢<���J���w� �$£�¤x¡w¥��  ��v¡¢+�+�J���x� �$£�¤w¡x¥��  v��¡¦¦ §s¨�©sªs« ¬ ­x®J­s¯v°�± ¯�²=³[´�§�µ ¯�®J¶§s¨v©�ªs« ¬ ­x®J­s¯v°�± ¯�²=³�´C§�µ ¯�®J¶AgentSetupAgentSetup//defaultAccountdefaultAccount))pp a$u�!wz�õ��Mu��+rC·<¸®dsr�uxza$u�!xz�õ��<u��<r�·M¸®dsr�uwz�� ¢<���s¥�¤w� �s�0�v¡g� ¹w��¹<��� �Eº�����¡g�w�s�&�J¡��¢+�w�=¥�¤x� �s�0�v¡4� ¹w��¹+�w� �Eº�����¡g�w�s�0�J¡w��� ¢<���J���w� �$»E¤w¡x¥��  ��v¡¢+�+�J���x� �$»E¤w¡w¥��  v��¡¦¦ ­=¯v°�©�ªsµ ¼�± ¯[²=³[´C§�µ ¯�®J¶­=¯v°�©�ªsµ ¼�± ¯�²s³[´�§�µ ¯w®J¶

ipAddressipAddress))

Slide 3.27: Global Variables

3.9.1 Nonpermanent Variables

Nonpermanent variables are lost after an agent restarts and use fewerresources than permanent variables. They will remain resident in theagent’s memory as long as the agent keeps running. A KM developercan freely assign any name for a global variable using the get() andset() function. The unset() function will remove the variable from theagent’s memory. These variables are read-write.

Using nonpermanent global variables allows developers to pass in-formation from one PSL process to another. Nonpermanent variablesshould be used when you want someone to enable debug on an instance.In that case, you can set the following variable:

Page 74: Advanced KM Development

66 The PATROL Virtual Machine

set("/<MYAPP>/<myinst>/parameterdebug","TRUE"),

And every parameter can check whether debug was turned on byusing get("../parameterdebug");.

3.9.2 Permanent Variables

Permanent variables include configuration and system variables andrequire extra resources when they are executed.

Configuration Variables

Configuration variables are stored inside the configuration database ofthe agent. They remain resident during the life of the agent even afteran agent restart because the agent reloads its configuration databasewhen it is started.

You normally access these variables by using the pconfig() functioncall. This call always goes to the configuration database and costs op-erations more than nonpermanent variables do. Even a read operationwill go to the configuration database so that the configuration databasecan be updated from outside the PATROL agent (using the OS pconfigcommand). These variables are read-write.

Note: You might have noticed that a normal get() operation will workon these kinds of variables also. It will have the same cost as usingthe pconfig() call.

System Variables

System variables are any variables that are executed on the host OS ondemand, for example : /ipAddress.

3.10 Local Variables

Local variables are private for each PSL process and are initialized atthe start of the process. The following describes the types of local vari-ables.

Named : A name is assigned to the variable by the programmer.

Page 75: Advanced KM Development

3.10 Local Variables 67

Unnamed : A name is not provided, and the PATROL agent assignsone.

½Â�C��5U9������¿¾2%�������;�,'�ÁÀ��:���%&;����<�½Â����57��57�256��365BÂ����Ý�&�y�<�������y%&¾y:���%�;��=�J�

Ãà NamedNamedÄÄ Å å<��Ýy��ë �Û���6�2ë�î�å<� ' ì=%sìc�<��Ư�fí�ë �<Ç�ß �0Ç$(sìa�<��Þ�í %�î�íµ��Ý>Ýy��íÅ å<��Ý8��ë ���¯�6� ë�î�å<�E'�ì=%sìa�<�0Æ���í�ë �MÇ�ß ��Ç$(sìc�<��Þ�íE%�î�í���Ý>Ý8��íÃà UnnamedUnnamedÄÄ Å å<��Ýy��ë �«å$%�ì0Þ�íE%MÆ�ëJ'<� '�à���å$' ìc�<�&� Å é �|ÈÊÉ Å î���å�ìN���6� ë�î�å<��%�å<�Å å<��Ý8��ë �Cå$%�ìÈÞ�í %<Æ�ëJ'<� '�à���å$'�ìc�<��� Å é �&È]É Å î���å�ìW�¯�6� ë�î�å<��%�å<�

Slide 3.28: Local Variables

3.10.1 Named Variables

In a named variable, the PATROL agent creates a variable author andassigns it the value John Doe. The agent then executes the functionnthargf(author,1) and assigns the result to a second variable namedfirstname. The result is that two named local variables are created. Be-low is an example :

author="John Doe";firstname=nthargf(author,1);

Page 76: Advanced KM Development

68 The PATROL Virtual Machine

3.10.2 Unnamed Variables

In an unnamed variable, the PATROL agent automatically assigns aname because the programmer does not provide a name. Below is anexample :

firstline =nthline(cat(myfile),1);

In the example above, because a name was not provided for the sub-function cat(errorfile), PATROL assigns it a name. The former exampleexpands to the following:

unnamed var=cat(myfile);firstline =nthline(unnamed var,1);

This means that the output of every command is stored inside a vari-able (named or unnamed).

3.11 Where Variables are Stored

In summary, the main issues to remember about variables are as fol-lows:

Name your local variables; otherwise, PATROL will do it for you,and you will not be able to use them in your script later.

Use configuration variables only when necessary (resource usage).Beware of cumulative global variables (memory usage).

Page 77: Advanced KM Development

3.11 Where Variables are Stored 69

Kernelç��������9Õ

Memory Scheduler

��� �������

��� �������

��� �������

MemoryMemoryMemory

Ë0Ì a$!c ��uded�Í PatrolAgent

fhgei jCk:lnm:o]p�gejCqCrsMemory

ftg:i jCk:lScheduler

uvwu xyz{||}

uvwu xyz{||~

uvwu xyz{||�

Mem Mem Mem

Î " @MV<* "CÏ * ;=IJ* V " - #

1g@<N * "CÏ * ;=IJ* V " - #

◆ Config U * ;=I�* V " - # * ;=-�Z " @<V<* "CU *E;=IJ*EV " - #�A T<* A ;=- # IJK<-�@<)LKMI #�ÐLÑ config-KM* A * VM* # -EÒ�Ó◆5�@M) #�Ô ,.-&,?@<;=-�;=- # @ Ô ;[N - # Ó

◆Z+- AJÑ Ò4Õ0@<; Ð+# @M) A T+-�,Ö* # Õ0- "J"J×M# *�,.-�N @ #BA * # :<N @M)+\[IJZ Ñ F Î|Ø�Ù G ×=Ú Ò

Slide 3.29: Where are variables stored

3.11.1 browsing the namespace

This section was added because it is one of the very frequently askedones. Here is one of the ways to do it...

function print parameters(instpath){

local parm, parms, parmpath;

parms=get vars(instpath,"subnodes");foreach parm (parms){

parmpath=instpath."/".parm;if ( get(parmpath."/__type__") == "PARAM_INSTANCE"){

print(" PARAMETER : ".parmpath."\n");}

}

Page 78: Advanced KM Development

70 The PATROL Virtual Machine

}

function print instances(applpath){

local inst , instances, instpath;instances=get(applpath."/instances");

foreach inst (instances){

instpath=applpath."/".inst;print(" INSTANCE : ".inst."\n");print parameters(instpath);

}}

function print applications(){

local appl, applications, applpath;

applications=get vars("/","subnodes");

foreach appl (applications){

applpath="/".appl;if ( get(applpath."/__type__") == "APPLICATION"){

print("APPLICATION : ".appl."\n");print instances(applpath);

}}

}

print applications();

3.11.2 Namespace and attributes

The PATROL namespace is a hierarchical structure of objects. The hier-archy is made up of the following objects, with each their own attributes.

• root object ’/’

Page 79: Advanced KM Development

3.11 Where Variables are Stored 71

• application class level

• application instance level

• parameter level

Each of these objects have a set of attributes. Some of them areshown on the slide below. Besides the builtin attributes, the namespacealso contains configuration variables and user defined global variables.The local variables are local to a PSL process and not accessible in thenamespace.

Attributes

- appType- hostname- ipAddress

Attributes

- name- active- instances

Attributes

- name- sid- worstParam

Attributes

- name- value- interval

/ ÛÝÜßÞàÞàá?â�ãäÜæåçâ�èêéìëîíïÛðâ+éòñóåÁÜôéàãöõÁëîí <PARAMETER>

Slide 3.30: Attributes in the PATROL namespace

3.11.3 Context of a PSL process

When a PSL process is started, it gets launched in a certain context.The context for PSL processes is shown below

Page 80: Advanced KM Development

72 The PATROL Virtual Machine

í÷Û2ÜøÞàÞóá?â�ãäÜæåçâ�èêéìëùíúÛ]â+éòñóåÁÜßéàãûõçëùíúÛ9ÞÁÜôüóÜøýþõçåàõóüòë

Discovery

Prediscovery

ÿ�������� � �� �� ������� ��� commands

��� �� � � ���� � ���

"!�#�$&% !('�) #�*�+ $-, .

Slide 3.31: Context of a PSL process

3.12 Executing inside and outside the VM.

As demonstrated, executing inside the VM isn’t always the best way.Consider a large file (20 MB). The moment you use a cat() statement

in your PSL code, the agent grows by 20 MB.If you do not give the output of the statement a name, PATROL will

create an unnamed variable for it. The contents of the file will be storedin memory.

PSL does not offer some sort of internal and magical IPC4. This is aconcept usually known by “shell developers” since IPC is a common wayto pipe data from one process into the other. Command in PSL are notevaluated as separate processes (like “shell” works) and therefore thereis no need to pass data in such fashion.

4interprocess communication. This is the same as communication over pipes (stdoutof process 1 = stdin of process 2).

Page 81: Advanced KM Development

3.12 Executing inside and outside the VM. 73

/ Ø���Ó�ï¢Ò]�³×�ðpÑ¬× Õ�� ÷ � ÷ ïpÒ2Ѭ×�ÕÄ�³Ò���1032546�75��8�9�:;61<>=�?A@3BDCFEHGJI?>6�9�9�K;L�IM<>=�?Ò�ONFP;?>K;L�IMK�L@�1<>K;:�6◆W ) # IJK<- Ï 7

grep(mystring,cat(myfile));orfilecont=cat(myfile);grep(mystring,filecont);

å$%*� Û ì�íµ�sÞ�í %Moµ���6�o�í�����ìc� 'RQ=%�í grepping

ä��$%�ß �AQ�ë�ß � - o %�å�ìa��å�ìc��ä�ë�ß�ß�S<��Þ�ß¾�Moµ� '�ë�å��åUT ï�åWV�å<��Ýy� 'UX���í�ë �(S�ß �ATTÝy�ðÝð%�í (YVÞ�ß ��ì;Q[%�í�Ý independant

◆Y Ô<AJ# IJK<- Ï 7Z���P\[(8 �-<>K;:�6^]_I�?>6�9 $mystring

` � Û ì�íµ�sÞ�í %Moµ���6�o�í�����ìc� 'RQ[%�í grepping,Ta�aQ[%�í0o��fì�à��bQ=%�í grep)å$%*� Û ì í��<Ý��ðÝ %�í (së�åWXM%�ßcX¯�E'�à ned\fhgï<�6��� f ��æÞ�ß ��ì;Q[%�í�Ýø'<�ðÞ<��å$'J��å�ì

Slide 3.32: Execute Inside or Outside the VM ?

Page 82: Advanced KM Development

74 The PATROL Virtual Machine

Page 83: Advanced KM Development

Chapter 4

KM Design

4.1 What should a KM Do

iÂà %&���/��,��&�Ý�>�l�����>�����(:ikj����<�����/ ��������=�+�&:�:l3757;=����56%��':���%&����;��2579&57�2$

ll ProPro-- �0Ó9Ò2×;m��*��m��7×�ó:��np×�ó�×�Ò>o@��ó:��� Ô Ñ�7Ó�Ò8×�m��*��m��0×:ó���n¢×:ó ×�Ò>o@��ó:��� Ô Ñll 2 ���7ÑPï����ÝiË����p ÷ � Ô ��ð¢Ó��³Ò ÷ × Ô Ï�� ÷ m�� ÷ Ï�������Ò2× ÷ ð���ó2 ���0ÑPï����ÝiË����p ÷ � Ô ��ðpÓ��³Ò ÷ × Ô Ï�� ÷ m�� ÷ Ï������7Ò8× ÷ ð���óproductivityproductivityll qÙ÷ ������Ó5Ò2× ÷ ð_�0Ò8Ò��ð¢Õ��9Õ ÷ �Ãï�ð��7Ò2Ò]��ð¢Õ���Õqµ÷ �����9Ó5Ò2× ÷ ð_�7Ò2Ò]��ð¢Õ���Õ ÷ �Ãï�ð��0Ò8Ò��ð¢Õ��9Õll AdministrationAdministrationll q �0Ï��7Ó9× Òho Ï�ó���ð�ð¢×�ð"r@��ð¢Õ_���9Ï ÷ �9Ò2×�ðsrq �7Ï��0Ó9×�Ò>o Ï�ó:��ð�ðp×Qð"r@��ð¢Õ ���9Ï ÷ �9Ò2×:ð"r

Slide 4.1: Expected functionality of a KM

75

Page 84: Advanced KM Development

76 KM Design

4.1.1 Better productivity

The goal of a KM is to present information instead of just data, in amanner that the customer can understand and use and in a way thatthey are comfortable with to interpret the information.

4.1.2 Get all info about application

Link knowledge about the application and how users use it and give allthat knowledge back to Patrol users

Talk to the DBA, to the end users, and developers and always talkto the support organization to get management and administrative fea-tures that are the most important. Support organizations are alwaysbombarded with customer requests and “How do I”-question.

Ask them what are the main problems are, what most people callsupport for?

If support says 30% of the calls are because of configuration issues,you might want to create a parameter that checks the configurationof the application (you might even check the configuration of the KM,because the KM will probably require some support as well).

Sometimes a simple check can significantly decease the support calls.It might be even more basic/simple to do then what you are thinkingabout.

4.1.3 Definition of a good KM

So how do you define a good KM versus a bad one ? Developers mightthink they wrote the best KM possible, because it lists every metric onecan possibly capture from the application. This is definitely not thedefinition of a good KM.

You might even be on a bad track if your KM just displays a ton ofinformation or even worse, a ton of raw data. If the intelligence is lim-ited to displaying every possible value you can retrieve then you shouldconsider the KM to be quite dumb, because the added value of the KMwill be limited.

Some KM’s leave the intelligence up to the end-user and requires somuch user interaction in the form of response() functions that it wouldcompromise the KM’s usability and scalability.

Understanding the definition of what a good KM is impacts yourdesign in many ways. The amount of functionality to be provided, the

Page 85: Advanced KM Development

4.1 What should a KM Do 77

way in which you handle instance creation, the number and types ofparameters as well as the user interaction you provide are all impactedby this difinition. So let’s look at what a good definition might be.

Proactive availability alarms

The KM should certainly sound the klaxons when the application hasgone down. But it should also predict downtime before it occurs by giv-ing you a chance to fix the problem before locked-out users start callingyou. Proactive detection of problems takes many forms. For example,degradation in performance is a warning symptom that the KM canmeasure. Similarly, space problems or an upward trend in space usagecan be measured, and application failure can be predicted and broughtto the attention of the administrators before it happens.

Performance

The measurement of the performance of an application is valuable bothas an indicator of availability problems and as a tool for tuning the ap-plication, and thereby improving the operational productivity. Measur-ing the real performance of the application with the KM can take theguesswork out of tuning the overall performance of the application.

Correction

When the KM detects a problem, can it fix it? Your KM can fix it viawhat PATROL calls a “recovery action.” It can also prompt the operatorbefore performing the action. Alternatively, you might just want noti-fication via pager, e-mail, or sending a trap or ticket to your help desksystem.

Administration

Availability and performance metrics can be categorized as “monitor-ing” metrics. The other side of that coin is “management” or “admin-istration” of the application. This refers to the user taking interactiveaction on the application.

In some cases it is desirable to add administrative features to theKM. It is possible to build a KM that is entirely administrative in func-tion. Usually an administrative KM will be highly interactive and re-quire extensive use of the PSL response function. A different form of

Page 86: Advanced KM Development

78 KM Design

administration KM might be “silent” and be comprised of automatedactions (Recovery Actions) to automatically respond to agent-detectedproblems.

Should your KM design be of the administrative type, you may wantto include some of these traditional adminstrative functions :

• Application startup and shutdown

• Configuration Changes

• Performance Tuning

• User Administration

• Security Changes

• Archiving or Restoring Data

Capacity planning

Capacity planning is also called “the gentle art of convincing your bossyou need more.” Although not as critical for short-term operational sta-bility, another important issue for long-term productivity is the mea-surement of the overall performance of the system. This involves met-rics such as performance time and resource usage to determine whenincreased usage trends will require new hardware or other big-ticketitems

Page 87: Advanced KM Development

4.2 General Guidelines 79

4.2 General Guidelines

t Intrusivenessuu / ð�����ð¢Ó��9ÕAÒ���*�0Ï¢Ï�ó ×�Ó��7Ò2× ÷ ð¢ÑJv�w]ï�ð¢Ó9Ò2× ÷ ð���ó ×�Ò>x/ ð�����ð¢Ó��9Õ�Ò���*�7Ï¢Ï�ó × Ó��0Ò8× ÷ ð¢ÑWvyw]ï�ð¢Ó9Ò2× ÷ ð���ó�× Òhxuu z ��x Ò ÷M{ �*ð ÷ ðz ��x Ò ÷|{ �*ð ÷ ð --intrusiveintrusiveuu } �9Ð-����� ÷ w�Õ���~���ó ÷ Ï Ô ��ðpÒT��whw ÷ �9Ò} ��ÐY����� ÷ wòÕ���~���ó ÷ Ï Ô ��ð¢Ò ��w�w ÷ ��Òtk���<�QP�%&� �!%�� ê �����øÀ�%�����;����uu LogfileLogfileuu �Ù÷7Ô°Ô ��ð¢Õ8ó�×�ð��*�7Ó9Ó��9ѬÑ�µ÷�Ô°Ô ��ð¢Õ_ó�×:ð��*�0Ó9Ó���ѬÑuu SNMPSNMPuu ò-��w ×�ð��*�M2 ��ð������ Ô ��ð�Ò��úiòÖò,��w8×:ð��*�|2 ��ð������ Ô ��ðpÒe�ÁijÖ

Slide 4.2: General Guidelines for KM development

4.2.1 Non-intrusive Application Management

The definition of non-intrusive application management is that it doesnot require application modification and uses existing interfaces. Mostapplications have some interfaces to collect information about them.Good KM design suggests that you use these interfaces where possible.

The alternative is to modify the application to provide managementinformation through SNMP or build a command line tool using the ap-plication’s API. This is far more complicated and in many cases simplynot possible.

Page 88: Advanced KM Development

80 KM Design

4.2.2 Finding Data Sources

� ò,�9Ò��� Ô ×�ð��*� ÷ Ð�� ÷ ï��³Ó�ï¢Ñ¬Ò ÷�Ô ���9Ñ Ô ��ð������³Ò���9×:�*�7Ï¢Ï�ó ×�Ó��0Ò2× ÷ ð�� � ��ï<�7��� Û ë � ì�ë�å�î*�Bo�í�ë�Þ�ìa�� ��ï<�6�&� Û ë � ì�ë�å�î*�Bo�í�ë Þ�ìc��� � ï�ì[%�Ýy��ìc��� Û ë � ì�ë�å�î*�<o�ì�ëJ%�å<�Û��å$'����Bo���ß ��ì ëJ%�å�íE%�ï�ì ë�å<���� ï�ì=%�Ýy��ìa�&� Û ë � ì�ë�å5îl�<o�ì�ëJ%�å<�Û��å$'y���Bo���ß ��ì�ëJ%�å�í %�ï�ì�ë�å<������µ÷�Ô°Ô8÷ ð�2 �5Ò]� ÷ ÕpÑ�� ÚÜÛ ë �2ì ë�å�î*�Bo�í�ë�Þ�ìc��TÚÜÛ ë � ì�ë�å�î*�Bo�í�ë�Þ�ìa��T PerlPerl à ãW��� àà ãW��� àRexxRexx))�� ProcessesProcesses�� � ë�ß ����T='<��ìc�� ë�ß ����T['<��ìa�

-- log)log)�� SNMPSNMP�� RegistryRegistry�� SubSub-- Þ�í %Moµ���6�Û� Û � o�ï�ì�ëJ%�åUTÞ�í %<o����6�Û� Û � o�ï�ì ëJ%�åRT cmdcmd ß�ë�å<���MoEo����6�FVß�ë�å<�&�<o o����6�FV�� APIsAPIs

Slide 4.3: Finding Data Sources

There are numerous sources of data from which to collect managementinformation in a non-intrusive fashion. Listed below are some of themost commonly used interfaces:

Scripts :If you already have scripts written in shell, Perl, SQL, C, orany other language, you can reuse them.

Processes : is a system process up, zombied, or down? How much CPU,memory has it used?

Sub processes : If the application has a batch or an interactive command-line executable for accessing the application, you can use the exe-cutable to get information or to send commands to the application

Files : The presence or absence of a file can have significance. The size

Page 89: Advanced KM Development

4.2 General Guidelines 81

of a database file can be a parameter. Archiving or removing a filecan be a useful administration command.

Log Files : plain-text error or history files can yield alert situations orprovide historical perspective.

SNMP MIB(s) : Get the data from the management information base(MIB) for the application. There are PSL functions specifically foraccessing values via SNMP.

Environment variables : The environment can contain useful infor-mation such as installation directories. In some cases an applica-tion will work without environment variables being set. You haveto know if this is the case.

Ports : Some applications that initiate network connections will be vis-ible in netstat output.

API’s : If the application offers a published API, such as C or C++, youcan access the application by this method. Typically, you woulduse the API to build an executable that is launched by the KM asa sub-process.

Performance Counters - Registry - (Windows NT only) : The Win-dows NT registry and performance counters often contains appli-cation information.

4.2.3 Extending Existing KMs

Another source of useful data is other PATROL KMs that are runningon the same agent. If your application is ORACLE-based you can getdata out of the ORACLE KM. However, there is a fine line betweenadding value to your KM and creating a dependency on another KM.Nevertheless, if there is a consistent dependency between your applica-tion and another application already monitored by a PATROL KM, thenwhy not save yourself time?

Page 90: Advanced KM Development

82 KM Design

KMsKMs

���R���y�����������¡ ���¢y£KMs¤¦¥ ~+���h§ and ô õ�d©¨sªg� {¤d«« !�uw~¤dsu�¬"­fõ r�­fõ�d-®<uwuw�\¯+� d��c±° u�!xu>¯!�u�~�dsuy¬s­fõ r�­�õtd®<u�ux�\¯+� ds�]c±°Euw!wu>¯²² get(“ /ORACLE7/instances” );get(“ /ORACLE7/instances” );«« !�uw~¤dsu#d=uwrv~+{�õ �(¯&{�õ�d:d©¬�c !>¯|���+tQcE!xz�õ�r�� c �jõ��(¯òõ±¯Y¯òõ�{M{+}�� �8õ r�� cE�Ëd�{+ux����t��!�u�~�dsu5dsu�r�~+{�õ �Y¯|{�õ�ded©¬�c !>¯|� �<tCc !wz�õ�r�� c��jõ��Y¯jõ±¯�¯jõ�{<{<} ���2õ r�� c �Ëd�{+uw�w� tv� ��{fõ�!2õ z u�r�ux!d��{fõ�!8õ z u�r�ux!d«« ³ uF¬¢õ !�u#c t�¯<u�{Mu��Y¯<uw�+�w��u]d-´¶µ Ë �¸·�·¶¹³ u>¬¢õ !�u#cEt�¯+uw{<u��(¯+ux�+����ud-´�µ Ë �¸·º·¶¹

Slide 4.4: Extending Existing KM’s

Data available from other KMs can take a few forms. First, the dis-covery phase might benefit from the already discovered icons for thedatabase. Rather than discover Oracle servers yourself, you can usePSL within the agent to get the ORACLE KM instance list through aPSL get on the internal instances variable such as :

inst list = get("/ORACLE7/instances");

The values of measured parameters from other KMs are easily avail-able within PSL in the agent via the PSL get() function. These valuescould be included in arithmetic to get a more application-specific perfor-mance metric or some other measurement.

If you use existing KMs beware that the KM may change with newreleases or that the data returned may change.

Also you have to degrade gracefully. If the data isn’t there you needto run without it or fail discovery and tell the user that you are depen-dant on the other KM

Page 91: Advanced KM Development

4.3 Portable KM design 83

4.3 Portable KM design

PortabilityPortability

»Â���'5U�!:�%&���������8����9����l���� &�/%&¾��½¼áà ���]�ø¾�%&��� %0¾��:�:�3657;�����5U%&�Ý�!%���57��%&��56�� >�����'�!������ ����(�����L57�b��,�����&�<��0157��, 01,�56;�,'��,���¼�à ;����' ��+:l%����2���'�-%>�>���=0,��&���l01�&����%����<%&¾��201�����/:�36��� ¾2%&���¿¾

»Â���������b��,����y�0¾ ¾-��;��8��,��/:�%������� l573757�2$�%&¾8�À¼áÃÁÁ  Ï������7Ò2×:ð"� ÑÃ�0ѬÒ� Ô Ï������0Ò2×:ð"� ÑÃ�7ѬÒ� Ô -- ò.×;ÄhÄ]������ðpÓ��9Ñ�Å���Ò8Ð-����ð�Ò��� ��Ø7Ò]����ð���óò.×;ÄhÄ�������ð¢Ó��9Ñ�Å��9Ò2ÐY����ðAÒ]���Ã�9Ø0Ò�����ð���óÐ ÷ ��ó�Õ ÷ ÄeÆ ×:ðÜÕ ÷ Ð6Ñ�ÇÉÈ ��ð¢ÕËÊ,ð¢×�ØsÌÐ ÷ ��ó Õ ÷ ÄeÆ ×�ðÜÕ ÷ ÐOÑ�Ç3È ��ðpÕ�Ê,ðp× ØAÌÁÁ Í Ï¢Ï�ó�× Ó��7Ò2× ÷ ðÍ Ï¢Ï�ó ×�Ó��0Ò2× ÷ ð -- ò.×;Ä>Ä�������ð¢Ó���Ñ<×�ð8� ÷ Ð Ò]���*�0Ï¢Ï�ó ×�Ó��0Ò2× ÷ ð8��ï�ð¢Ñò.×�ÄhÄ]������ðpÓ��9ÑÁ×:ð_� ÷ Ð Ò���*�7Ï¢ÏÄó�× Ó��7Ò2× ÷ ð_��ï�ð¢Ñ×:ð�բ׺ÄhÄ]������ð¢Ò�Ó ÷ ð¢Ò]��Ø7Ò2Ñ×�ð�Õ¢×�Ä>Ä]������ð¢Ò�Ó ÷ ðpÒ�9Ø0Ò2Ñ

Slide 4.5: KM Portability

4.3.1 Introduction

An important advantage of a KM as a form of application monitoringand management is the ease with which the KM can be ported to a newhardware or software platform.

This advantage is achieved through the portable infrastructure layercreated by the agent, KM, and PSL features of PATROL. However, PA-TROL cannot fully insulate the KM developer from the idiosyncrasiesof the various platforms. Although all base PATROL functionality isportable, the boundary between PATROL and the outside world is thepoint at which PATROL loses control; and as a KM developer, you willneed to know what to deal with. Two main areas can affect a KM:

• Operating system : Differences between the external world of Win-dows NT, Unix, Linux, VMS, . . .

Page 92: Advanced KM Development

84 KM Design

• Application : Differences in how the application runs in differentcontexts

Both of these areas have their own issues.

4.3.2 Portable agent functionality

The PATROL agent is a virtual layer of abstraction above the operatingsystem on which it runs. The KM executes within the agent’s spacerather than directly on the operating system. The agent insulates theKM from a number of portability issues. All the purely agent-relatedfunctionality within the agent is portable across all the various agentplatforms. For example, the internal PSL syntax, operators, and controlstructures are portable.

4.3.3 Portability Issues at the Interface with the OS

Areas of nonportability arise at the interface with the operating system.The agent must gather information from the operating system, and thisinformation is necessarily different on different agent platforms. Thus,issues such as files, processes, and spawned executables exhibit differ-ent behavior. Although PSL insulates against some of the porting is-sues, it is not possible to hide all of the differences, nor would that bedesirable.

4.3.4 Portable Areas of PSL

The PSL language is portable for all the specific areas of functionalitythat occur fully within the PATROL space. Unless the PSL function hasto go to the external operating system, all the functionality is identicalacross all operating system ports of the PATROL agent. Some of thespecific areas where portability is ensured are as follows:

Control Flow : Basic statements such as if, else, while, foreach, andswitch

Operators : mathematical, string, logical, relational, conditional, andternary

String functions : includes nthline and other string functions, list/setfunctions, and sorting

Page 93: Advanced KM Development

4.3 Portable KM design 85

Agent symbol table : variables controlled via PSL get, set, and otherPSL functions

KM objects : fully portable instances, parameters, recovery

Inter-PSL actions : PSL locks, condition variables, and other syn-chronization primitives

4.3.5 Non-Portable Areas of PSL

The areas where PSL has to access the operating system for informationare the causes of nonportable functionality. Although the functionalityis generally the same, the results of these operations depend completelyon the external environment. Some of these areas are as follows:

NonNon--

ÎÂ�ÁÀ��57�b:l%������� �36�yÏ& ����8�<:���;=56��3������������257%�� 56�b����Ð���56�����¾�%��ÑÑ Ò ×:ó��*�7Ó9Ó��9ѬÑ�Ó�ï�ð¢Ó9Ò2× ÷ ðpÑÒ ×�ó:�*�0Ó9Ó���ѬÑ�Ó]ï�ðpÓ�Ò8× ÷ ð¢ÑÑÑ iË� ÷ Ó��9ѬÑÁÒ��Ô�ó:�*��ð���ó;�0Ѭ×�Ñ�Óï�ð¢Ó9Ò2× ÷ ð¢ÑiË� ÷ Ó���ѬÑ<Ò��Ô�ó��*��ð���ó;�7Ñ¬× Ñ�Óï�ð¢Ó9Ò2× ÷ ðpÑÑÑ Õ �¢×:ó Õ�Ï�� ÷ Ó��9ѬÑSó:��ï�ðpÓ��Ü×:ð&�Õ �¢×:ó�ÕAÏ�� ÷ Ó��9ѬÑSó:��ï�ð¢Ó��Ü×�ð"�ÑÑ / ð"Ö7×�� ÷ ð Ô ��ð¢Ò�Ö����9×���Ô�ó:��Ñ/ ð"Ö0×:� ÷ ð Ô ��ð¢ÒAÖ����9×:��Ô�ó:�9ÑÑÑ ×sØ 2îiÙÓ�ï�ð¢Ó9Ò2× ÷ ð¢Ñ×"Ø 2ùiÙÓ]ï�ðpÓ�Ò8× ÷ ð¢ÑÑÑ internalinternal

Slide 4.6: Non-Portable Area’s of PSL

File access functions : file, cat, fopen, fseek, ftell, read, readln, write,and close

Process table analysis functions : process, proc exists

Page 94: Advanced KM Development

86 KM Design

Child process launching : system, execute, popen, read, readln, write,close, and the ”exit status” special variable

Environment variables : getenv

Special areas : PSL internal function

SNMP functions : snmp get, snmp set, and snmp walk

These items are not considered non-portable, because the functionswill behave exactly the same on all platforms, but sometimes the argu-ments you have to supply to these functions to make them work couldbe significantly different.

4.4 Portability examples

problemsproblemsÚÚ ÛAÜ�Ý�Þ�ß�àáß�Ý�âAãäÞáâså�â�ÛsæÉÝ�âAÞÛsÜ�Ý�Þ�ß�à�ßyÝ(â�ãäÞ�âså�âAÛAæ3Ý�âsÞ

popenpopen Þ�ç�âsÜ�èêéÞ�ç�âsÜáèëélnln ì è3íáîëï¡Ýì è3í�îêï�ÝÝ�çsð¡ã ñÝ(çsð¡ã ñ

\\r ”r ”ÚÚ òÉçsí�ÛAâsß�ßAé ì ð_ßóî3íáÝMæÉòÉè3ÜáÝ(âAèõô�í�çkâsÜáÛsöHÛsÜ�÷¡÷ò3çsíáÛsâsß�ß�é ì ð_ßËîÉí�Ý|æ3òÉèÉÜ�Ý�âsèHô�íáç½âAÜ�ÛAöõÛsÜá÷�÷ÚÚ øúù Ûsí�ãûãäÜáî3è3ßóô�í�çkÛsö3ð¡÷¡èõò3çAí�ÛAâsßyß�â�ß½éøüù ÛsíáãûãäÜ�î3èÉßËô�í�çkÛsöÉð�÷¡èHò3çsíáÛsâsßyß�â�ßké ÷_ß÷_ß íáç½èÉð�ç ìí�çkè3ð¡ç ìÚÚ ý î3Ý�âsçsòÉçAâAÝ(ÜáÝ(ð¡í�îHí�ôOâså�ð�Ý�þ�ß�Ý(ÜáÝ(æÉßý î3Ý�âsçAò3ç�âsÝ(ÜáÝ(ð¡íáîõí�ôOâAå�ð¡Ý(þáß�Ý�Ü�Ý�æ3ßÚÚ ÿ çAâsÜ�Ý�âkè3Ü�â�ãäí�îHò3çAíáÛsâAß�ßyâsß éÿ çsâsÜáÝ(âkè3ÜáâAãäí�îHò3ç�í�ÛAâsß�ßyâsß é òÉí�ò3âAîò3í�òÉâsî ð¡ßóÝ�öÉâð�ßóÝ�ö3â

solution)solution)

Slide 4.7: Examples of Portability Problems

Page 95: Advanced KM Development

4.4 Portability examples 87

4.4.1 Carriage Return Characters (NT, VMS)

Carriage return characters pose a portability problem on Windows NT,and VMS for processing text data. Unix platforms separate text filelines with a new line character (that is, "\n" in PSL vernacular).

Windows NT, and VMS all use a pair of new line ("\n") and carriagereturns ("\r") characters to separate lines in a text file. This issueposes problems in PSL in a number of areas related to text data:

• PSL cat() on a text file

• PSL system() or execute() returning text data output by a childprocess

• PSL read() or readln() on a popen() channel returning text dataoutput by a child process

The effect is that the string variables containing text data from thesesources will still contain the "\r" characters. This is problematic be-cause the PSL string operation functions do not treat the "\r" charac-ters as special and will only consider the "\n" as the separator.

For example, if you use the PSL function ntharg() to return thefirst or second line, the returned line will still contain a "\r" character.This character is also difficult to see when debugging the script withdebugging output statements.

There are no PSL functions that handle "\r" characters as sepa-rators for lines. Some of the places that this poses a problem whenprocessing these strings are as follows:

Line and word processing : ntharg(), nthline(), nthargf(), nthlinef(),PSL foreach() statement

Regular expression search : grep()

List or set operations : union(), subset(), difference()

The solution for this problem is to trim the carriage return characterimmediately after the input was read.

trim(xx, "\r");

The solution to the "\r" problem is a pragmatic, if not particularlyelegant, solution. The PSL trim() function can be used to remove these

Page 96: Advanced KM Development

88 KM Design

characters before processing the string data. You have to rememberto remove these characters every place where the KM gathers externaltext data. However, it is only one line in each such place. An exampleinvolving PSL cat looks similar to the following:

text = cat(pathname); # Get the text data contents of a filetext = trim(text, "\r"); # Remove all rcharacters from the textOne possible method of handling this problem is to wrap all calls to

PSL cat(). Wrapping requires calling another wrapper function insteadof PSL cat(). each time, as shown in the example below:

function portable cat(fname)2 {

local text , save errno;4

# Get the text data contents of a file6 text = cat(pathname);

8 # save errno just in casesave errno = errno;

10

# Remove \r characters from the text12 text = trim(text, "\r");

14 # reinstate errnoerrno = save errno;

16

return(text);18 }

Listing 4.1: Portable cat() function tabsize

Not all places have this problem with the "\r" character. One placewhere the carriage return character is automatically handled is the PSLfile reading operations. The PSL read() function on a channel openedvia PSL fopen() (with a non-binary mode) will not return the carriagereturn characters in the output. PSL read will automatically removethese characters from the returned result.

Page 97: Advanced KM Development

4.4 Portability examples 89

4.4.2 process() function (all platforms)

Operating system processes are another area where portability con-cerns arise. Processes are an integral part of the operating system layer;and although PSL attempts to hide some of the differences, some prop-erties of OS processes are not abstracted.

The main abstraction layer for gathering statistical performance dataabout processes is the agent’s process cache. The only reason it is calleda cache is that it records a snapshot of the process information withinthe agent’s memory for rapid access. This cache is a regularly updatedrecord of operating system processes and a number of statistics aboutthem. The process cache is available via the PSL process() function.For example, the process cache contents can be viewed via :

# List all agent process cache processes print(txt);txt = process("*");

The process cache is built automatically via the agent. The PSLprocess() function is very efficient because it only operates within theagent’s internal data structures and does not perform external processanalysis. Behind the scenes, the agent uses a platform-specific methodto gather the data.

Gathering platform-specific data may be direct operating system statis-tic access (for example, Windows NT) or a system command (for exam-ple, ps on some Unix platforms). The process cache is updated accordingto the process cache cycle, which is by default 300 seconds (5 minutes)but can be configured on a per-agent basis by the PATROL administra-tor. The process cache can also be updated immediately via the built-in%REFRESH PROC CACHE agent command, which can be launched asan ad-hoc command on the system output window or via PSL, using thePSL system() function with this command.

The process cache has a number of limitations. It may be out of date,possibly by almost 300 seconds. The process cache cannot be updated forone particular process only. The whole process cache must be updatedas a group. This requirement poses problems for a KM that needs to getregular up-to-date information about a small group of processes if thisdata is needed more frequently than the process cache update cycle.

Portability of the PSL process function to all agent platforms is alsosomewhat limited to non-Unix platforms. All Unix agents should func-tion identically, but some of the attribute fields are not always availableon agents running on other platforms.

Page 98: Advanced KM Development

90 KM Design

The solution for the delay in refreshing the process cache can besolved by using the PSL proc exists() function. This function alwaysimmediately queries the process tables and has up-to-date information.However, its only value is in the presence or absence of a particular pro-cess, and the function returns only a Boolean value. PSL proc exists()cannot gather any other more detailed statistics about a process. It alsorequires the PID of the process and cannot be used to search for pro-cesses based on the name.

4.4.3 Launching Child Processes (all platforms)

The affected functions are : system(), execute(), and popen().Child process launching is an area with a number of portability con-cerns. The behavior of the child processes may differ, or they might noteven exist on a particular platform. The KM can launch child processesinto the operating system in a number of ways using any of the previ-ously mentioned functions.

The first problem with child process launching is whether the com-mand exists on a particular platform. For example, the Windows NT dircommand fails on Unix, and the Unix ls command is usually absent onWindows NT.

The first level of portability is to ensure that the correct command isexecuted on the correct platform.

There is no easy way to achieve this execution other than to ex-plicitly check the platform, which is possible via the appType variable.Ported KM code might often look like the following:

# What type of agent am I2 platform = get("/appType");

if ( platform == "NT" || platform == "VMS")4 {

cmd = "dir";6 } else {

# Presumably UNIX8 cmd = "ls -la";}

10 txt = system(cmd); # Launch the command}

Listing 4.2: Example of ported system functions tabsize

Page 99: Advanced KM Development

4.4 Portability examples 91

4.4.4 Child Process Error Handling (all platforms)

The affected functions are : system(), execute(), and popen().Launching the wrong command on the wrong platform causes the com-mand to fail. Unfortunately, PSL does not handle this issue as elegantas one would like. The agent will launch a child process attemptingto run this command. On Unix, it will typically use a shell; and onWindows NT, it will use the command interpreter to attempt to run thechild process. The errors returned by the PSL system(), execute(), andpopen() functions are therefore dependent on the behavior of the shellor command interpreter, and differ across platforms.

On Unix, the text returned from a PSL system call that fails is typ-ically a shell-specific error message. This message differs depending onwhether sh, csh or ksh is the default shell for the PATROL user.

Similarly, the messages on Windows NT are from the OS commandinterpreter rather than PATROL-specific error message text. It is pos-sible to check for the error message patterns, but this is not the bestsolution.

The PSL exit status variable can be used to determine the exit codeof the child process. This exitcode may come from the shell or commandinterpreter, but it is generally accurate because they usually pass alongthe child process code or have a valid failure code if the command isnot found. The exit status might have a different meaning on each OS.It is likely that a process on UNIX that exits with a 0 return code hascompleted successfully, however on VMS, this might indicate a problem.

4.4.5 Preventing Command Failure

Prevention of command failures is not easy. There is no way in PSL toprevent an invalid command execution before launching the child pro-cess. There is no PSL function that will check the PATH environmentvariable and determine whether the command is valid and available.

4.4.6 Child Process popen() Pipes

The PSL popen() function launches a child process and creates pipesbetween the agent and the standard input and output of the process.PSL write() can thus send commands to the process’ standard input,and PSL read() can read the results from standard output and stan-dard error. This function is typically used with global channels to use

Page 100: Advanced KM Development

92 KM Design

a command to interact with the database or application that the KM ismonitoring.

4.4.7 Launching Daemon Processes (all platforms)

The creation of child process in the background is a particular problemfor a KM. The typical scenario is a KM that needs to relaunch a daemonprocess in a recovery action once it determines that the daemon is fail-ing or absent. Because of the manner of child process launching usingthe Unix shell on some platforms, some of the common attempts havefailed and will block the call to PSL system until the child process com-pletes. For example, below is a simple try on Unix using the & syntax:

# UNIX backgrounding with &−syntaxtxt = system("/etc/my_daemon &");

This scenario sometimes works and sometimes not, depending onthe Unix platform and on the daemon itself. Some of the failing plat-forms occur because the shell is waiting for the file descriptors of thechild process. Hence, the following Unix csh syntax sometimes im-proves the portability by hiding the file descriptors from the shell:

txt = system("/etc/my_daemon >&/dev/null &");

This descriptor is not shell-specific, and the solution to the shellportability issues leads to either a separate shell script file that is launchedseparately or explicit coding of the shell in the command, such as the fol-lowing:

txt = system("/bin/csh -fc \"/etc/my_daemon ".">&/dev/null &\" ");

When all else fails, the PSL popen() function comes to the rescue.The PSL popen() function has the property that it launches the childprocess and immediately returns control to the agent. Therefore, youcan simply call:

chan = popen("OS", "/etc/my_daemon");

This command will return control immediately to the PSL processand leaves the child process running. However, behind the scenes, alloutput from the daemon is stored in the agent’s memory. Therefore, abetter sequence is to detach the child process from the agent by closingthe channel, as shown below:

Page 101: Advanced KM Development

4.5 Options to Avoid in KM Development 93

chan = popen("OS", "/etc/my_daemon");close(chan); # close channel without killing child

Note that the PSL close() function is called without a second argu-ment. You should not use the flags in the second argument to kill thechild process because that is not the goal.

4.5 Options to Avoid in KM Development

DevelopmentDevelopment�ôÀ��������¿P�� �������������������ôÀ��������îP� ������������ Self- � ����������� � � � � ���!�������� * ������� � ���"��#��%$&�'�)(*��,+-���)������.0/1�!#��!���32�� 4 ��� ���6578���9.'� �:5;� ���6���0�����<��=�����>

Slide 4.8: Options to Avoid in KM Development

Just because a feature exists doesn’t always mean you should use it. Forexample using a response function in discovery is possible but could re-sult in your KM never instantiating because no user was at the consoleto provide the input for the script to continue.

The PATROL development console has many options to choose from,and sometimes it can be difficult to know what to do with them all.

Page 102: Advanced KM Development

94 KM Design

Some of the options you should try to avoid using in your KM includethe following:

State Change Actions : These are console-centric actions and there-fore are limited to OS commands. They are not very powerful andgenerally are left alone.

Setup Commands : Ignore setup commands because as these com-mands run once at the start of the agent, they are not useful in aKM. You can get the same “once only” execution through predis-covery by doing the once-only action just before converting predis-covery to discovery.

Self-Polling Parameters : Avoid the button in the scheduling dialogbox for parameters.

Interactive Tasks : All the tasks have a “Task Is Interactive” button.Generally, it should be left alone.

History Level : History level is best left as inherited

in transition : Old PSL function that serves no purpose anymore.When first called, a transition timer is started for <timeout> sec-onds and the value 1 is returned. While this timer is running,subsequent calls also return 1. After the timer expires, calls toin transition() will still continue to return 1 until the next fulldiscovery cycle, after which it will finally return 0 and reset thetimer. The timer is also reset by calls to change state().

change state : A function with a lot of side-effects. If you call change state()on an instance with parameters then this will automatically sus-pend the execution of all these parameters. It’s better to let one ofthe parameters under the instance go into alarm, since this alsoallows you to add recovery actions if needed.

Simple Discovery : Maybe this is useful for entry level KM’s, but thisoption definitely lacks the options if you really want to be in con-trol. You achieve the same functionality as simple discovery bywriting some simple PSL scripts. Because of the lack of controland functionality, we will not spend any time on Simple Discoveryin this book.

Page 103: Advanced KM Development

4.6 KM Tracing and Logging 95

Menu Command %%{. . . } macro : This macro will ask for user inputand subsitute the result in the menu command text prior to send-ing it to the agent. Since this is a literal replacement, inproperinput by the operator can result in compiler errors.

Statically linked libraries : It is possible to statically link libraries.This feature has not been used at all and is there for historicalreasons.

4.6 KM Tracing and Logging

If you develop a KM you want to be sure that you can remotely diag-nose problems with the KM. Therefore it is a good idea to think aboutdebugging and tracing early in the development process.

There are a lot of options to turn on debugging (usually via an ad-ministration response() function. The output can be written to file orsystem output window.

If you write the output to file, don’t write it to the agent’s error log.The agent error log is indeed ”The agent error log” and not ”km errorlog”.

Page 104: Advanced KM Development

96 KM Design

Page 105: Advanced KM Development

Chapter 5

Optimizing PSL

Before you ship your code or install it on production machines, youshould at least go through a performance analysis cycle of your KM.That means measure how much CPU your KM is consuming and if youcan solve the performance bottlenecks. After a while you develop a feel-ing for what the more expensive calls are under different circumstances,but before you are there, you will have to go through a lot of KM analysisand optimize a lot of PSL code yourself.

When you think of optimizing PSL, you should have some under-standing about what the PSL optimizer will do for you. Once you un-derstand that, you can focus on the areas that are your responsabilityas a developer.

97

Page 106: Advanced KM Development

98 Optimizing PSL

5.1 Measuring Performance

?_I9@A?0BDCFE�Z�STNFB?_I9@A?0BDC�E7Z�STNFB

G�HJILKNMLOQP!RTSVUVKQOXW�Y Z!KQW�[�ILKNMLO<P!RTS\UVKX]LY![�Y^R_P ON`badcMLO<P!eQKQWfW�K<W�[TP^[TILKXMLOQP!R�SVUVKNY W�[TILKQg&[TK<O<hiSkjLY![�K!l

G�HJILKNY m!K<jL[fnoW�]LY![�Y&SVjpeQUkqp]LKQW�[TILK�rss t*uwvXxwy�z|{D}!~��w�F�wz�{D��y��T��y��p�wz�{D}k����y��t*uwvXxwy�z|{D}!~��w�F�wz�{D��y��T��y��p�wz�{D}k����y��ss � ���D�w�_y��N�k��v�y {Q}!�V�wy|�D�Dy��w�� ���D�w�_y��N�k��v�y|{D}!�V�wy|�D�Dy��w�ss �*uwvXuw���D�V���Dy �8~���k��v�y {<} �k�wy|�D�Dy��w��*uwvXuw���D�V���Dy|�*~���k��v�y|{Q}!�V�wy|�D�Dy��w�ss � �Dy�z��D�Dy����8~����{D�D�N{D}!�k�wy|�D�Dy��w�� �Dy�z��D�Dy����8~����{D�D�N{Q} �k�wy|�D�Dy��w�

Slide 5.1: PSL Profiling

5.1.1 Standalone compiler/interpreter

It is possible to test your standalone psl scripts by using the standalongpsl compiler/interpreter. After you ran your psl with profiling mode en-abled, you can run ppv (PATROL profile viewer) on the result to exam-ine the profiling result

Page 107: Advanced KM Development

5.1 Measuring Performance 99

� KOY7Z��&\6Y7Z����VY7LON ?_I9@A?0BDCFE7ZËSÀN¡B� KOY7Z��&\6Y7Z"�¢� Y7L6N ?_I9@A?0BDCFE7Z�STN¡B

£¥¤¢W�Y!j%P!ML[�SVP!j%¦�ILK<j�W�[TY!O<[�Skjpm&[TILKNY m K)jp[§ ¨�©!ªw«�¬o­|® ¯ °�±p²)«§ ¨�©!ªw«�¬o­|® ¯|°�±p²)« --profilingprofiling£¥¤¢W�Y!j%P!ML[�SVP!j%¦�Sk[TI%[TIpKX`bawc9e<P!hiMLSVUVK<O³)´ ®³)´ ® --PP£¥Z SVY^`badc:¤¢`¶µ·· ProfDefaultOptions()ProfDefaultOptions()·· ProfOptions()ProfOptions()

Slide 5.2: Activating the PSL Profiler

5.1.2 Agent Command Line option

You can start the agent in profiling mode (-profiling). When you do thatthe agent will generate a profile file that contains profiling informationabout all PSL processes that were running in the agent while it wasrunning.

Again, use ppv to examine the profiling result.

5.1.3 From PSL

If you just want to profile a piece of your PSL code, you can enable PSLprofiling on a very granular level. There are a couple of PSL profilingfunction which are all explained in deep detail in the PSL referencemanual addendum.

Page 108: Advanced KM Development

100 Optimizing PSL

E0¸_Z��¢� Y7L6N ?_I9@ ?0BDCFE�Z�STNFB0¹_Q¡�OK.Y7ZºC0�¢¸E0¸_Z��¢� Y7L6N ?_I9@ ?0BDC�E7Z�STNFB0¹_QF�6K.Y�ZkC0�¢¸

» ProfDefaultOptions ¼ options )½½ ¾D¿XÀ�ÁkÁkÀ�ÂwþD¿�À�ÁkÁkÀ�ÂwÃoptionsoptions Ä�Å ÁkÆ Ä ÂwÇpÁVÈ Å|É Æ Ä�Ä�Å ÂwÁ Ê Å�ËkÌ ÆwÍ�ÁVÇÄ�Å ÁVÆ Ä ÂwÇpÁVÈ Å|É Æ Ä�Ä�Å ÂwÁ Ê Å�ËºÌ ÆwÍ�Ákǽ½ Êw¾ Å ÇpÂw¾DÁ ÌD˺ËkÅ�É Á Å�Î À�ÇTÁkÀ�ÂwÃ�Ï Ä ¾ É�Å ÇTÇ Å ÇÊw¾ Å ÇpÂw¾DÁ ÌD˺ËkÅ�É Á Å�Î À�ÇTÁkÀ�ÂwÃ�Ï Ä ¾ É�Å ÇTÇ Å Ç» ProfOptions ¼ pid Ð options )½½ Å�Î À�ÇTÁVÀ�ÂwÃ�Ï Ä ¾ É�Å Ç_Ç Å Ç É�Ì ÂXÑ Å Ò Æ Å�Ä À Å ÊN¾ Ä|É È Ì Âwà ŠÊÅ�Î À�ÇTÁVÀ�ÂwÃ�Ï Ä ¾ É�Å Ç_Ç Å Ç É�Ì ÂXÑ Å|Ò Æ Å�Ä À Å ÊN¾ Ä|É È Ì Âwà ŠÊ

Slide 5.3: Using the PSL Profiler Functions

?0BDCFE!Ó9Ô6Y Õ�ÖØ×ÚÙOYdÛFÙOY?0BDC�E ÓÜÔ.Y Õ�ÖØ×ÝÙ6YdÛFÙOY

Slide 5.4: Profiler Output

Page 109: Advanced KM Development

5.2 PSL optimizer 101

5.1.4 Profiler KM

The Profiler KM can be downloaded from http://devcon.bmc.com andautomates the profiling process. Although the profiler KM will add sig-nificant load to your agent, it will be reasonably easy to get a variety ofreports about performance impact of your KM.

5.2 PSL optimizer

This section is a collection of the slides we will discuss in class.

Þ��OY BDCFßØÙ¢à.Y7ZkC0� YáCVY â�Ô ?Fã9@ ×ÝÛ6Y0Z�[VZkä�Ô¡BÞ"�6Y BDCFßØÙ¢à.Y�ZVC0� YáC Y â¢Ô ?Fã9@ ×ÝÛ6Y0Z�[VZkä�Ô¡B

å¥`6adcçæ¢Mp[_SVhiSkè<K<ON¤�OQeQILSV[_K<e<[TqpO<Kéé ê�ëwì�í�í|î�í�ïDí�îê�ëwì�í�í|î�í�ïDí�îéé multimulti--passpasséé ð�ñwòVí�ì�ó�í�ôwð�õDòVí|ö�÷Dôwí|÷DøwòVðùóXð�ú�í�ìð�ñwòVí�ì�ó�í�ôwð�õDòVí|ö�÷Dôwí|÷DøwòVðùóXð�ú�í�ì

å¥`6adcçæ¢Mp[_SVhiSkè<K<ONû¶qLjpe<[TSVP!jpWå%awMLK<e<SkR�g SVjLm^P!Mp[_S\P!jpW

éé ü*÷Qó�ó�õDñwôXî�ð�ñýíü*÷Qó�ó�õDñwôXî�ð�ñwíéé þ�ì�õDÿQó¢õ�þ������TòVõ<òVí�ó�í�ñdòþ�ì�õDÿQó¢õ�þ������TòkõQòVí�ó�í�ñdò

Slide 5.5: Introduction to the PSL Optimizer

Page 110: Advanced KM Development

102 Optimizing PSL

@¢Ô��NÔ��º¸ CFEØ×ÚÛ��� ��kä�����ºC0�@¢Ô��NÔ��º¸ CFEØ×ÝÛ���� ��kä�����ºC0�

��adqLMLMLP!O<[TK<]%UVKQZ!KQUVW�� �� -- � ÷�÷Dø��VðùóXð�ú�õ��kð�÷Dñ� ÷�÷Dø��VðùóXð�ú�õ��kð�÷Dñ�� �� --

�������� �"! ø�����ø�#w÷� $��% ÷Dø��kð�ó�ð�ú�õ��kð�÷Dñ�&�'���� ��! ø�����ø�#w÷� $��% ÷Dø��kð�ó�ð�ú�õ��kð�÷Dñ�� (( --

�������� )( ! �÷Dö�õ� *% ÷Dø��kð�ó¢ð�ú�õ��Vð�÷Qñ�&�'���� )( ! �÷Qö�õ� *% ÷Dø��kð�ó¢ð�ú�õ��Vð�÷Dñ�� ++ -- �������� )+ ! ÿ� �÷QÑwõ� *% ÷Dø��kð ó�ð�ú�õ��kð�÷Dñ�&�'���� )+ ! ÿ� �÷DÑwõ� *% ÷Dø��kð ó�ð�ú�õ,�Vð�÷Qñ

Slide 5.6: Levels of Optimization

@¢Ô��NÔ���-@¢Ô��NÔ���-–– . Ô/ C��XÔ�0ظ�Ô��kÔ�¸�¸21FÙ� Û¢¸. Ô� C��XÔ�0ظ�Ô��kÔ¢¸¢¸21FÙ� Û�¸

35476985:{

a++;}

;=<?>�@BA5C/D5E/F 3G4IHJ88 <LKNM�O 8PQ<?>�@BA5C/D5E/FF�<�R�S�T�U;=<?>�@BAVCND5E/P 3G4IHJ88 <LKNM'O 8PQ<�R�S�TWU

Slide 5.7: Level 1 Remove Useless Jumps

Page 111: Advanced KM Development

5.2 PSL optimizer 103

@�Ô¢�XÔ/�-@�Ô¢�XÔ/�-–– . Ô¢ß0Ù¢à¢Ô21¡Ù�  ÛYX9â������¢¸. Ô¢ß0Ù¢à¢Ô21¡Ù� ÛYX9â������¢¸

ZJ[]\_^a`ZJ[]\_^a`{{ ZJ[]\ bc`ZJ[]\ bc`

{{A+=1;A+=1;

}}}};=<?>�@BAVCND5E�d 3G4IHJ88 <?>�@BAVCND5E�e 3G4IH ;PQ<LKNM'O 8F�<?>�@BAVCND5E�ee�<?>�@BAVCND5E�dd�<�R�S�TWU

;�<L>�@BAfCgD5E�F 3G4IHh88 <L>�@BAfCgD5E�F 3G4IH ;P�<iKNMGO 8FQ<"R�S�TBU

Slide 5.8: Level 1 Reduce Jump Chains

@�Ô¢�XÔ/�-@�Ô¢�XÔ/�-–– . Ô� C%�NÔ . Ô�ßØÙF�¢ß��¡�IjÝÙ��¢ß. Ô� C%�NÔ . Ô¢ß0ÙF��ß��¡�IjÝÙ��¢ß

a=1;a=1;

a=1;a=1;

a=1;a=1;

a=1;a=1;

;=<LKNO 88 <LKNO 8PQ<LKNO 8F�<LKNO 8e�<�R�S�TWU

;�<iKNO 88 <"R�S�TBU

Slide 5.9: Level 1 Remove Redundant Quad

Page 112: Advanced KM Development

104 Optimizing PSL

@¢Ô��NÔ���-@¢Ô��NÔ���-––

?���à�k ?��FBf�� Ô�DÔFBQ¸?���à�k ?��FB��/ Ô�DÔFBQ¸

l=mGn5oGpqm5r9s,t�uwvGx,y*pqm5pquwt,n5zwm5p|{�}�p5pG~ ���_vq~ x"s�r�}�t�{�pq},���G�l=mGn5oGpqm5r�s�t�uwv5x�y*pqm5pquwt,n5zwm5p|{�}�p5pG~ �,� vq~ x"s�r�}�t�{�pq},���G��,z�~ pq~ p��&~ � �5t�pGvG�"~ ��� v'�5v5�G�|m5x��w�q}�{�y$~ u"~ �WvG�"nGz�mGx�s�v5p�y$z�vq}�r9��vGr�,z�~ pq~ p|��~ � �Gt�pGvG�"~ ��� v'�5v5�G�qmGx��w�q}�{�y$~ u"~ �WvG�"nGz�mGx�s�vVpqy$z�vq}�r9��vGr}���pG}�u"vq�*t�x�n5y*~ }�x�pqmGx��w�&~ � �G��vGnGr�v5mGpGvq��t,mG�"nG}���v�pG~ �Wv}���pG}�u"vq�*t�x�n5y*~ }�x�pqmGx��"��~ � �G��vGnGr�v5mGpGvq��t,mG�"nG}���v�pG~ �Wv

;=<�CW�V�W��A�ONK8 <�CW�V�W��A�O��PQ<�CW�V�W��A�O/�F�<�CW�V�W��A�Og�e�<�CW�V�W��A�Og�

;=<�CW�V�W�'A,F�ONK)�L�����8 <�CW�V�W�'A�PgOg�����

Slide 5.10: Level 1 Pack Parameters

@¢Ô��NÔ����@¢Ô��NÔ����––

ãI B����¥���"C��������¢�ãI B����¥���"C��������¢�

x=join("b",join("c","d","e"),"f");x=join("b",join("c","d","e"),"f");

print(x);print(x);

���&�a �¡a £¢G¤¦¥�§h¨�©WªWª�«G¬"­G¬"§a¨�©Wª�ª�«®����a �¡a £¢G¤¦¥i¯�¬w§a¨�©Wª�ª�«G¬�°±)���a �¡a £¢'±�¥¦²V¬´³¤,�qµh¶W³a·£¸£¹5®L¥�ºh»�¼c½�¾À¿£¿£¿�Á ���a �¡a £¢'±�¥�µa¶�³a·�¸£¹G®'¬�ÃÄ �qµh¶W³a·£¸£¹'±¦¥�ºh»�¼c½�¾À¿£¿£¿�ÁÅf���a �¡a £¢'±�¥�µa¶�³a·�¸£¹�±5¬´ÆÇ ��È�¥�ºh»W¼a½É¾À¿£¿£¿�ÁÊ����a �¡a £¢'±�¥�§a¨�©Wª�ª�«G¬´ÈËf�qµh¶W³a·£¸£¹5®L¥L¸�Ì�¼c½£¶É¾c¿£¿�¿�Á®£����ÍÀÎGÏcÐ

�����c B¡a £¢G±¦¥�§a¨�©Bª£ª�«G¬dcebfag®��ÒÑ�Ñ�¥i¸�Ì�¼c½£¶É¾À¿£¿£¿9Á±)��Í£Î'ÏcÐ

Slide 5.11: Level 2 String joining

Page 113: Advanced KM Development

5.2 PSL optimizer 105

@�Ô¢�XÔ/�i�@�Ô¢�XÔ/�i�––

¹¢CÓ�kßY�¡�¢ß ÛFBDC0Û��¢����QÔ¹�CI�kßY�¡��ß Û�BáC0Û��¢����DÔ

DEBUG=0;DEBUG=0;Ô []\ ÕhÖJ×JØaÙ£`Ô []\ ÕhÖJ×JØaÙ£`{{

print("DEBUG");print("DEBUG");

}}

print(1+2+3);print(1+2+3);���&Ú£Í�ÛÀ©WÜ]¥]�®��|Ýa©À¢B�¦¶B»  ¼WÃNÞßڣۣͣ©Wܱ,�&�a �¡a £¢'±�¥�§h¨W©Wª�ª�«G¬´Ú£Í£Û�©Wܤ���µh¶W³a·£¸£¹5®L¥i¸'Ì�¼c½£¶�¾À¿£¿£¿àÁ �&�a �¡a £¢�¥¦§a¨�©Bª£ªW«Ä ��µh¶W³a·£¸£¹5®L¥�®?á�±ÅV��µh¶W³a·£¸£¹'±¦¥�µa¶�³c·£¸£¹G®?á�¤Ç �&�a �¡a £¢�¥]µa¶�³c·£¸�¹�±Ê���µh¶W³a·£¸£¹G¤?¥i¸'Ì�¼c½£¶�¾À¿£¿£¿àÁËV�&ÍÀÎGÏcÐ

����Ú£Í�ÛÀ©WÜ]¥]�®���Ýa©À¢B��¶W» ±)���a �¡a £¢G±¦¥�§h¨W©Bª£ª�«G¬´Ú£Í�Û£©WÜ ���a �¡a £¢G±¦¥�§h¨W©Bª£ª�«G¬?ÅV¿â���£�����£�Ä �ÒÑ£Ñi¥i¸�Ì�¼a½�¶É¾À¿£¿£¿9ÁÅf��ÍÀÎGÏcÐ

Slide 5.12: Level 2 Fold and propagate

@�Ô¢�XÔ/�i�@�Ô¢�XÔ/�i�–– . Ô� C%�NÔ�ã Ù��à��"Û��kÔ2�¡��ß. Ô� C%�NÔ�ã Ù��à��"Û��kÔ2�F�¢ß

Ù��FÙ¢¸¢Ô�ßåä0Ô�E��"������ºC0�¢¸Ù��FÙ¢¸¢Ô�ßåä0Ô¢E���������kC0��¸

a=1;a=1;

a=2;a=2;

a=3;a=3;

b=1;b=1;

print(a);print(a);���|­�¥]®®��|­�¥¦±±,�|­�¥�¤¤��毥]®Â �&�a �¡a £¢'±�¥�§h¨W©Wª�ª�«G¬"­Ä ��µh¶W³a·£¸£¹5®L¥i¸'Ì�¼c½£¶�¾À¿£¿£¿àÁÅV�&ÍÀÎGÏcÐ

�����a �¡a £¢G±¦¥�§h¨W©Bª£ª�«G¬�¤®��ÒÑ£Ñi¥i¸�Ì�¼a½�¶É¾À¿£¿£¿9Á±)��ÍÀÎGÏcÐ

Slide 5.13: Level 2 Remove Multiple and unused Definitions

Page 114: Advanced KM Development

106 Optimizing PSL

@¢Ô��NÔ����@¢Ô��NÔ����–– . Ô�CØBQßFÔFB0Û��FB��/ Ô�QÔFBQ¸. Ô¢C0BQßFÔFB0Û��FB��/ Ô�QÔFBQ¸

ç�è }��5vqx�vGp5y*vG�"vGéG{�r�vGp5pG~ }�x�p�}�t�y�}���mGx��"��vG�$}�r9vqy$z�v|{,mGr�mGu"vGy$vGrp5vG��t�vGx,nGvG�5�,z�~ pqmG� � },��pqy$z�v|ê,ë|}�{�y$~ uw~ �WvGr=y$}w{,vGr9�$}�r9uÉm5����~ y$~ }�x,mG�{�m5r9mGu"vGy$v5r={�mGn5oG~ x�s��x=join(a+1,a+2,a+3);print(x);

���&�a �¡a £¢�¥¦§a¨�©Wª£ªB«®��qµh¶W³a·£¸£¹5®L¥]­¦á�®±)���a �¡a £¢�¥]µa¶W³a·£¸�¹G®¤,�qµh¶W³a·£¸£¹'±¦¥]­¦á�±Â ���a �¡a £¢�¥]µa¶W³a·£¸�¹�±Ä �qµh¶W³a·£¸£¹G¤?¥]­¦á]¤Åf���a �¡a £¢�¥]µa¶W³a·£¸�¹'¤Ç ��È�¥�ºh»W¼a½É¾À¿£¿£¿�ÁÊ����a �¡a £¢'±�¥�§a¨�©Wª�ª�«G¬´ÈËf�qµh¶W³a·£¸£¹5®L¥L¸�Ì�¼c½£¶É¾c¿£¿�¿�Á®£����ÍÀÎGÏcÐ

����µh¶W³a·£¸£¹5®L¥�­�á�®®���µh¶W³a·£¸£¹'±¦¥�­�á�±±,��µh¶W³a·£¸£¹G¤?¥�­�á]¤¤��&�a �¡a £¢G¤¦¥�§h¨W©Wª�ª�«G¬iµh¶�³À·£¸�¹G®'¬@temp_2 �&�a �¡a £¢�¥]µa¶�³c·£¸�¹'¤Ä �&È�¥�ºh»W¼a½É¾c¿�¿£¿�ÁÅV�&�a �¡a £¢'±�¥�§h¨W©Wª�ª�«G¬´ÈÇ �´Ñ£Ñi¥�¸'Ì�¼a½�¶É¾c¿�¿£¿9ÁÊ��&ÍÀÎGÏcÐ

Slide 5.14: Level 2 Reorder Parameters

@¢Ô��NÔ���ì@¢Ô��NÔ���ì–– . Ô/ C��XÔ�09�FBQÔ��¢àFâ���í��kÔ. Ô� C��XÔ�09�FBQÔ���àFâ���í��kÔ

codecode

DEBUG=0;6ßî RGï�@5ð :gñ]ò�ó�3Bô D 6Jõhî R'ï�@Gð õ�: < ò�ó�3Wô D 6hõàö5÷Nî RGï�@5ð õW:Vø

���&ڣۣͣ©WÜ�¥��®��|Ýa©c¢��¦¶W» ı,�&�a B¡c £¢'±�¥¦§a¨W©Wª£ªW«G¬´Ú£Í£Û£©Bܤ��´Ñ£Ñi¥�¸�ÌW¼a½£¶ù¾c¿£¿�¿9Á �&ÍÀÎ'ÏÀÐÄ �&�a B¡c £¢'±�¥¦§a¨W©Wª£ªW«G¬�¨Wú�Ú�Í�ÛÀ©BÜÅV�´Ñ£Ñi¥�¸�ÌW¼a½£¶ù¾c¿£¿�¿9ÁÇ �&ÍÀÎ'ÏÀÐ

���&�a �¡a £¢'±�¥�§h¨W©Wª�ª�«G¬�¨Wú]Ú£Í�ÛÀ©BÜ®��´Ñ£Ñi¥�¸'Ì�¼a½�¶É¾c¿�¿£¿9Á±,�&ÍÀÎGÏcÐ

Slide 5.15: Level 3 Remove Unreachable code

Page 115: Advanced KM Development

5.2 PSL optimizer 107

@�Ô¢�XÔ/�iì@�Ô¢�XÔ/�iì–– . Ô¢ß0Ù¢à¢Ô�ûü�kCFà�kýXÜâ��/�"�¢¸. Ô¢ß0Ù¢à¢Ô�ûü�kCFà�k2X9â������¢¸

þ�ÿ },{������ }�nGo5pqvGx�y$vGràvG�w�V~ mqt�x�nG}�x��,~ y$~ }�x�m5���ât�u"{�pqy*}"��vqmG���9mGn5vGx�y�y$}the jumpfrom

��� }�nGo5��� y�� }�}�oq�*}�r=mq��� }�nGoqy*z�mGy�n5z�mG~ xwy }w��� }�nGoGpy*z�mGy�m5r9vq��~ s�s,vGr=y*z�m5x��q�&~ y*z"mGxwt�x,nG}�x���~ y*~ }�x�mG�Gv5~ y�m5x��"~ p|x,}�ymG� r�vGmG���qy*z�vqx�v5y���� },nGo��$}�r�~ y*pGvG� � �*�þ�� v5mGp5}�x��B�*� }��&s�r9mG{,z optimizationÔ []\ �À`Ô []\ �À`{{

b+=1;b+=1;

}}

elseelse

{{

b+=2;b+=2;

}}

print(b);print(b);

����� Ô��£Ô��������! ����#"����� Ô��£Ô��������! ����#"Ô []\ �À`Ô []\ �À`{{

b+=1;b+=1;

print(b);print(b);

exit;exit;

}}

elseelse

{{

b+=2;b+=2;

print(b);print(b);

exit;exit;

}}

Slide 5.16: Level 3 Reduce Block Chains

×ÝÛ���W �ºä�ÔFB��¡��ß ãÝÔF�FÙYX0CI � ý�F�¢ßF¸%$&$&$×ÝÛ��W �ºä�ÔFB��F�¢ß ãÚÔF�FÙYX0CI � ý�F�¢ß�¸'$&$�$(*) K<jpq e<P!hhiY!jL]LW�Y OQKNe<P!hiMLSkU\K<]%R_P!ObK<Z K<OQgK�+ K<e<qL[�SVP!j ¼ SVR SVj `6adc WfP qpO<eQK-,

(%æ�ML[TSVhSVè<Y![�SVP!j%SVW/.Lg^]pK<R_Y!q Uk[�0 ¼ Z10�l 21,33 EveryEvery-- 465�798;:=<?>@4A<?B1<?CD465 795 E=FG465 <?H9I465�798;:=<?>@4A<?B1<?CD465 795 E=FG465 <?H9I expensiveexpensiveJLKJMKNN pragmapragma O&PLQ�RTSUPO&PLQ�RTSUP --zero)zero)33 Librar iesL ibrar iesNN V�WYXZW&[6\V�WYXZW&[6\

Slide 5.17: Optimizer and Menu Commands

Page 116: Advanced KM Development

108 Optimizing PSL

5.3 Architecture Optimization

5.3.1 Frequency of execution

When you program in PATROL, you will create many PSL processes,which are scheduled by the PATROL Agents scheduler. Every processwill require resources. Therefore, every effort should be made to limitthe number of processes and their execution schedule. This applies toall commands that will be automatically scheduled by the agent (pre-discovery, discovery, collector and standard parameters)

5.3.2 Amount of scheduled processes

You should try to limit the number of processes you add to the agent.Although PATROL is very efficient working with vast amounts of pro-cesses, there is no need to create them if you can obtain the same func-tionality without them. You might be able to combine a couple of stan-dard parameters into a single collector for example.

5.3.3 Amount of spawned processes

The use of global channels can reduce the number of child processesused by the KM and limit the number or redundant processes accessingthe application. Also careful use of the command type facility can reducechild processes

5.4 PSL Optimization

5.4.1 = , grep() or index()

These are three different functions to do string matching. The optimizerwill not change one command with another, each function has it’s ownreason of existence with its own backend code. I’ll try to spend sometime on each of the different functions and hope this helps you under-stand why it is working this way.

text = pattern

Returns 1 if regular expression pattern matches the text, otherwisezero. The text can be multi lined. This is an operator. An operatortakes two arguments are returns a third argument in a single QUAD

Page 117: Advanced KM Development

5.4 PSL Optimization 109

instruction. The operation is a regular expression match and it will un-conditionally behave like a very fast version of grep()... no options, nochecking, no return values, besides 1 or zero. Whenever the optimizercan, it will ”pre-execute” this operator at compile time. That means ifthe two arguments are static (hardcoded), using = will have no runtimeoverhead. The execution of = is fast (much faster than grep and I guessa little bit faster than index), but

• Will return 0 or 1

• Will always use regexp (be careful when your pattern contains reg-exp characters)

grep(pattern,text,options);

Returns the lines of text that match pattern. This is a build-in functionand will therefore require a quad more to execute than an operator.Has options to tweak the execution, and will try to determine if patterncontains regexp or not. It works line by line and if pattern does notcontain regexp it will use a sort of index() function (without compilingand executing the regular expression) to optimize for speed. This is theslowest of them all on a line mode, but a lot faster then writing yourown using = and foreach line on a block of text. The optimizer willnot ”pre-execute” the function, even if the arguments are hardcoded (orstatic).

index(text,string);

Does not work with regular expressions. It will return the position ofstring within text. Works on multilines and very useful to see if a cer-tain word appears in a block of text. This is a PSL function with lessoverhead than grep(). The optimizer will ”pre-execute” in case both ar-guments are hardcoded (or static)

5.4.2 multi-string grepping

The PATROL grep() function supports multiple string matching.

grep("string1\\|string2",text);

Page 118: Advanced KM Development

110 Optimizing PSL

5.4.3 PSL readln() limitation

The limitation of the readln() is that the length is limited to 4095 char-acters. Below is a function call SafeReadln which will readln and if theerr 57 occurs, try reading again until the EOL is seen.

longfile = get("/patrolHome")."/longfile.txt";

function Safe Readln(chan){

local psl , x , data;

pos = ftell (chan);x = PslDebug;# Turn off runtime error reportingPslDebug = 0;data = readln(chan);

while (errno == 57){

# E PSL READLN TRUNCATEDpos = pos + 4095;fseek(chan, pos, 1);data = data.readln(chan);

}

PslDebug = x; # restore runtime error reportingreturn data;

}

readchan = fopen(longfile, "r");if (! chan exists(readchan)){

print("error <".errno."> opening <".longfile.">\n");exit;

}

longbuf = Safe Readln(readchan);print("========== longbuf =============\n");print("long buf is <".length(longbuf)."> bytes long\n");print(longbuf);

Page 119: Advanced KM Development

5.4 PSL Optimization 111

print("=========- end of longbuf ========\n");

5.4.4 Evaluation shortcircuiting

Operators && and || do not short-circuit evaluation: The second operandof these operators is always evaluated and never short-circuited by thefirst expression.

]%^FÛ%_DÔ¢¸�¸���`0� ã9âa`b_�]%^FÛ%_DÔ¢¸�¸���`0� ã9âc`d_�--CircuitingCircuiting

ee 5 BAI�8=f?CDg=hjiaik8=f?CDg=l?JAmonqp5 B1I68=f?CDg=hjiaik8=f?CDg=l?JAmrn�pss t1uvxw-y z z�{�|&}�z ~�}&� {���������{ ���o�Z{Z�6� y��&��t1uvxw-y z z�{�|&}�z ~�}&� {���������{ ���o�Z{Z�6� y��&��� � { ������Yy��-{����{����y�|�{Z�a���� { ������Yy��-{����{��o� y�|&{Z�a�ee 5 BAI�8=f?CDg=hGJ�m�5 B1I68=f?CDg�l?JAmrn%p����5 B1I68=f?CDg=hGJAmY5 B1I68=fGCDg=l?JAmrn%p����ss w-y z z���}�~��6{�}���@� ��{Z�A�&|�{Z� ��{�}&��@�6�D�j}� �{A� ~��Z{?y��&y��-w¡�&��� �j� ��{�{ �U� �&�Z�w-y z z���}�~��6{A}&��@� ��{Z�A�&|�{Z� ��{Z}&��&���D�j}� �{A� ~��Z{?y��&y��-w¡�&��� �j� ��{�{ �U� �&�Z�

!!

Slide 5.18: Expression Short-Circuiting

Page 120: Advanced KM Development

112 Optimizing PSL

5.4.5 Optimize Loops

¢a`�`0Û ×ÝÛ�Q�W ��kä"����!`0�¢¸¢a`�`0Û ×ÝÛ�Q�W ��kä"����!`0�¢¸

£c¤¦¥A¥1§%µ¨�©�ªG«1¨�¬�¥1­¯®a©�°�±L²�¨�¬6¥1­£ Common Subexpression Elimination£ Pre- ³ ¥1´µ§L±L¨�¬�­�¶·¤¸¥A¥A§ µ­L¹A«1ªG¬6«1­L¨�º

Slide 5.19: Loop Optimizations

5.5 Performance not influenced by ...

Blocking PSL functions – For the PSL function that have blocking im-plementations (read, sleep and block) when they are blocked does notput the PATROL Agent into a blocked state or a busy loop due to theway PATROL schedules. They have no performance impact while theyare waiting

Menu and InfoBox commands – Menu commands and InfoBox com-mands are only executed when the user requests them (on the console).You can tune them however their impact will be less than those thatrun repeatedly

Recovery Actions – Recovery Actions run only when a problem occursand there therefore will yield less performance gain than those that runrepeatedly

Number of consumer parameters – Since consumer parameters haveno runtime presence, they cannot consume CPU time. You may see someperformance impact for history storage but this is usually marginal

Page 121: Advanced KM Development

Chapter 6

Prediscovery andDiscovery

6.1 History of Prediscovery and Discovery

To understand why prediscovery and discovery exists, we have to takea jump back in time. A long time ago (first versions of PATROL), theagent was not console independent (and therefore not autonomous). Ifa console connected to an agent, the agent would download all requiredknowledge from the console. Because the agent didn’t store the KM’s,they had to be resent to the agent each time a connection broke andwas reestablished. This caused a significant amount of overhead on thenetwork, since in a lot of cases a downloaded KM wouldn’t even run onan agent, because the application was not installed.

At that time there was only something called discovery. Discoverywas the first script that was ran right after the KM was downloaded tothe agent. Because in a lot of cases discovery would find out that theapplication was not installed, it was decided that it would be beneficialto introduce a step before discovery. Prediscovery was born...

If the prediscovery script existed, it was unconditionally downloadedto the agent. Only when prediscovery signals the agent that the activestate of the application changed to 2, the KM would be downloaded.

Later on (from PATROL 3), the agent was fully autonomous and thereal need for having prediscovery or discovery went away, but by thenit had introduced a whole new way of developing KM’s so the featureswere never removed in later versions.

Because some customers wanted to prevent KM’s from being loaded

113

Page 122: Advanced KM Development

114 Prediscovery and Discovery

altogether, based on some very simple rules, the “allow on” and “denyto” fields we added to the KM’s property tab. These will be translatedas pragma statements in the KM file. When an agent now loads a KM,the pragma’s will be checked first, then the agent will check the agentconfiguration database for disabled KMs and if this succeeds then theKM will eventually be parsed.

6.2 The Discovery Cycle

The “Discovery Cycle” is the process of going through prediscovery anddiscovery. This section will explain what this is all about.

PrediscoveryPrediscovery »½¼·¾¿¾ÁÀ=·÷ķÅ*ÆÈÇ�ÉËʵÇÌÄÈÃ#ÆÈÂÍ»½¼·¾¿¾ÎÀ=·÷ķÅcÆÈÇ�ÉËÊÈÇÌÄÈÃ#ÆÈÂ�ÂÏÑÐ�ÒTÓÕÔ1ÖØ×ÎÙ ÚÜÛÞÝàß�á�âaÔØãaã-â

-Ö1ä-å@ß�æ1ÖØå@â�åàçÜâ'è�é

ϽêØÒTë*â-å@â-ã�Ûìß�íMß�íÜîïß6íÜß�åàß�Ö¡á�ð�ÖØä-åàß�æØâ-ñïÖ1å@åàã�ß6òÜóMå@â�æØÖØá6ó�â

Prediscoveryô-õ-öø÷-ù6÷ÕúActive=1 Active=2

Y N

û�ü�ýAþ1ÿ ô������������ ÿøÿ��� �ü ô��6÷-ô�ù6ù�ö���������-ù�ö���ô��Üù ý������ ô�� predisc öU÷Õô����1ù �

Slide 6.1: Prediscovery and Discovery process

6.2.1 Prediscovery Or Discovery ?

After the KM has been parsed by the agent, the agent will determine thesetting of the active attribute. This initial value of active is determinedlike this :

Page 123: Advanced KM Development

6.2 The Discovery Cycle 115

• If prediscovery exists : 1

• Prediscovery doesn’t exist : 2

Depending on the setting of active, the agent will start either createa prediscovery or the discovery process. These scripts will not be com-piled unless they are about to be run. That means prediscovery can beused to check availability of a library (and load it) before discovery isrun. Discovery can then safely require the library. It is strongly recom-mended never to require libraries in prediscovery. If you safely want tocheck for existence of a library, you can do it like this :

function libtest(lib)2 {

local warn,alarm;4 # Check if lib is installed and loadable by the agent

# This is to prevent the compiler from complaining on use before set6 warn = "";

alarm = "";8

# Call PSL execute. The compilation results will be stored in10 # the warn and alarm variables

PslExecute("LIBTEST","requires ".lib.";",warn,alarm);12

# If we had a compilation warning or alarm, return 114 return((warn || alarm) ? 1 : 0);

}16

if ( libtest ("mylib.lib"))18 {

print("Unable to load library mylib.lib");20 exit;

}22

# Although you might be tempted to just load the library now, you should not24 # See chapter on libraries for this.

Listing 6.1: Safely checking existence of a library tabsize

Page 124: Advanced KM Development

116 Prediscovery and Discovery

6.2.2 Discovery and Prediscovery Processes

� À=·ÃÍÄïÅcÆÈÇ�É! ɵÃ#"�Æ� À=·ÃÍÄïÅ*ÆÈÇ�É$ ɵÃ#"�Æ

foreach(application)

%'&)( *,+)-/.)0)1OR

%REFRESH_APPL_DISC

0

1

2

( 2436587:9<;<;<=>7:( [email protected]*B&)?@1)0DC>EF<G@0).B*BHJIK&DL LM9<;<;�=KH@NPOQ0)1A*B./Rexit;( 2436SUTV0)G@( .D1W?XH>*,T:Y@?X?U( ?XZUE@F( 2,3 2B( TV.A*�[D*B( \K0DEUF�1)HU\]SU( L 0W3

prediscR<RTVY@?

predisc}( 2,3�G@( .D1)HP^_0)T IK?@H>*,T:Y@?@?U( ?XZUE@F( 2,3 2B( T:.B*�[)*B( \K0)E@F<1)H@\`S@( L 0/3�GX( .D1)HP^�0)T IUR<RT:Y@?`G@( .)1)Ha^�0)T I}

“ /APPL/active”

Slide 6.2: Discovery Cycle

The discovery process is a lightweight process in the agent (special typeof process) that will be executed each after each discovery interval. Af-ter each discovery interval, the agent will check the active flag of theapplication to find out if the discovery or prediscovery process should berun. The process will only be started if it was not running before.

A lightweight process can be seen as a high priority rtcell for theRUNQ scheduler and will therefore not be delayed in its execution.

All applications that use the default discovery interval (40 seconds)will be scheduled from the same lightweight process and the evaluationof active will start one after the other. The order for which KM will bechecked is the same as the KM loading order.

Every KM that has its own discovery cycle will create its own lightweightdiscovery processes. If you don’t require a 40 second execution of your

Page 125: Advanced KM Development

6.2 The Discovery Cycle 117

discovery scripts, you should modify the discovery cycle for your appli-cation.

6.2.3 Coding Style

Although prediscovery can be left empty, it is better not to do so. If youwant to skip prediscovery and execute discovery straight away, just typethe command

set("active",2);in your prediscovery script.

If you don’t need prediscovery nor discovery at all type an exit; inthe command.

Historically, the most common check to make in prediscovery pre-discovery is to check that the KM is not running on an incorrect agentplatform. This can be done by examing the /appType variable however,it is a lot better to use the allow on and deny to fields in the KM propertywindow.

Some people believe that the discovery process has to be the placewhere application instances get created. Although this is probably truefor at least one KM you write, all the instantiation can then happenfrom any process running on the agent. There is nothing bad in havingonly exit statements in both prediscovery and discovery. We will talkmore about instance creation in the next chapter.

6.2.4 Full and Partial Discovery

PATROL doesn’t know the difference between full or partial discovery.This is more or less the concept of trying to execute as few PSL instruc-tions in discovery as possible (remember that by default the schedule is40 seconds).

The idea behind full discovery is usually when your application wasjust loaded and still needs to find out all the details and perform setup ofthe KM. This step is supposed to be more expensive than partial discov-ery, where only an update to the current discovered environment needsto be made.

Although PATROL has no hardcoded states to support full or partialdiscovery, it provides some functions that can make it easier to check ifsome checking can be skipped.

If your discovery relies on the process() function, there is no needto execute the discovery script unless PATROL’s internal process table

Page 126: Advanced KM Development

118 Prediscovery and Discovery

was refreshed. The PSL full discovery() command indicates that arefresh of the process cache has happened since the last time discoverywas run. This function has not other purpose than notifying you theprocess cache was refreshed although some people seem to think thereis something magical about it.

If your discovery is based on a configuration file, your initial discov-ery cycle will have to read this file completely. After this initial setup, itwould be good to check if the file changed since the last discovery cycle.If it hasn’t there is no need to set everything up again. You can use thefile () function as a test to determine whether the file has changed. Thisfunction will return the last modification time of the file. You can savethe timestamp in a global variable.

# Set the filename2 filename = "/opt/conf/config.txt";

# get the timestamp of our configfile4 timestamp = file(filename);

# get the old timestamp6 # if first time it will be initialized to 0

oldtimestamp = get("oldtimestamp");8 # if timestamp still the same, exit

if ( timestamp == oldtimestamp)10 {

exit;12 }

# Now do your ”partial” discovery....14 # save the new timestamp

set("oldtimestamp",timestamp);

Listing 6.2: Checking for file updates in discovery tabsize

Page 127: Advanced KM Development

6.2 The Discovery Cycle 119

6.2.5 Unique Features of Discovery

b ¼ÈÀdcfe·ÆhgÍÆ·»ji�eÈÇ-ÆÈ Ä#k � À�ÂÍ÷ÄïÅ*ÆÈÇ�Éb ¼ÈÀAcfe·ÆhgÍÆ·»li�eÈÇ�ÆÈ Ä#k � À=ÂÍ÷ÄïÅcÆÈÇ�Émm npoVqDr@s<t�u@vXwxoVq]y{z�|K}~qDrXvUoV��s���������:oQr@���AoVs����Qu@t�u@�n�o:qJrUs<t�u@vXwxoQq`y�zp|K}~qDrXv@o:����s���������VoQrU���AoVs����Vu@t�uX�

�� �@���a�M���a�V�>�� �4�a���K�D�K���@�B�Q���U�>�� �P�)�a�X�Q��U�)�>�M���a�Q�P��6�,�>���`�)�K���@�B�Q���@�P��6�P�D�>�X�Q��� �D���������¡ )¢8�Q£A¤� )¢8�Q£A¥6¥6¥@¦�§�¨< ©�)��¦�¦� D�)¢ª�U«�)�U�������¡ )¢ª�Q£A¤U )¢ª�Q£A¥6¥ ¥U¦�§�¨< ©�)�U¦�¦� )�)¢8��«

Application

InstanceA InstanceDInstanceCInstanceB

P1 P3P2 P1 P3P2 P1 P3P2 P1 P3P2

¬/­/® ( .)1)H>^�0)T I<->+ ­ ;<&)TV&D\`0A*B0)T

Slide 6.3: Unique Features of Discovery

The discovery script is the only script that will execute on applicationlevel and will run even if no instances have been created.

The discovery script can be used to collect data as well (just likeany PSL script). In case you have a command that will return data forall instances of your application class, then you might want to considerputting the command in the discovery script. However, make sure toremember to update the discovery interval in that situation. Change itto the same scheduling you would have used if the collection logic wasin a parameter.

Page 128: Advanced KM Development

120 Prediscovery and Discovery

6.3 Discovery Pitfalls

� À=·ÃÍÄïÅcÆÈÇ�É!¯ÑÀdi�k-»°"�"=Â� À=·ÃÍÄïÅ*ÆÈÇ�É$¯ÑÀdi�k-»°"�"=±± PrediscPredisc²d³µ´�¶>·�¸º¹M¹M»µ¶/¼M½4¾µ¾4´�¾4¿ÁÀ_¶WÂÄÃ,ÅÆ»4¼XÇ_·M¹M¶P¶²d³4´�¶P·�¸º¹M¹M»4¶/¼M½µ¾4¾4´Q¾4¿ÈÀ�¶/ÂÄÃ,ÅÉ»4¼MÇ�·M¹M¶>¶ÊÊ %PSLPS%PSLPSÊÊ ËKÌ)͡Ϊ�UÏ)Î4Ð�Ñ�ΪÒ�Óp����Ô��UÕ�Ö�Ì)�U×)Î8Ñ�Ø��UΪÌ�Ù�@×)ΪÑ�Ø@��Î8ÌËKÌ)Í¡Î8��Ï)Î4Ð�Ñ�Î8Ò�Ó��U��Ô���Õ_Ö�Ì)��×DΪÑ�ØU��Î8ÌÙ�@×)Î8Ñ�ØU�UΪÌÚªÛÈÜ ×)Ò�����ÝUÌDÞÚªÛÈÜ ×)Ò��U��Ý�ÌJÞßß qDu@�dàAá�âVã�äWä/|�â:��rU�doVt<u@å�æ�ç<èÄoV���<��wxä©é�|êqDr@vXo:���qJuU�dàAá�âVãÁä©ä/|�âV�<r@�do:t<u@å�æ�ç<èÄoV�����wxäWé|êqJrUvXoV��oVë#ëluUì�o:���duU�Qwxì�u@qJ�dvUs�w�q`s�í_îDuUr@�AqoVë#ëlu@ìoV�<�du@�Vw�ìuXqD�dv@s<w�q`s�í�î)u@rU�Aqßß qDu@�dàAá�âVã�äWä/|�â:��rU�doVt<u@å�æ�ï<èÄoQëlë#u@ìoV�<�duX�:wqJuU�dàAá�âVãÁä©ä/|�âV�<r@�do:t<u@å�æ�ï<èÄoQëlë#u@ìoV�<�duX�Vw�V��ð�r@ñuXq]ìoQqDr@s<t�u@vXwxàAò�ñu@�{�s��Äw�u@��v@ð���o:��ó�è�V��ð��rUñ�uXq`ìoQqJrUs<t�u@vXwxàAò�ñ�uU�{�s��Äw<uU��v@ð���oV�ó�èßß ôöõ�÷øã�ùpõêúds�vÈá<ë#oVû<u@ìåxu@û�u@rUð��doQs���s<úôöõ�÷øã�ùpõüúds�vÁá�ë#o:û<u@ìåxu@û�u@r@ð�doQs���s�ú

prediscpredisc/disc/disc

Slide 6.4: Discovery Pitfalls

6.3.1 Prediscovery and Discovery running together

The agent will react immediately when the value of active is changed.set("/APPL/active",0) in any PSL script immediately destroys ob-

jects. set("/APPL/active",2) immediately launches discovery (when itwas not running yet), even when the agent is currently executing pre-discovery.

Since it is possible to have both discovery and prediscovery runningat the same time, you should be aware that this can result is some verybizarre results.

To make sure you don’t encounter this problem, it is a good practiceto only have a single set("active", ...); call in either the prediscoveryor discovery script. If you have multiple statements that modify theactive flag then type a exit; function after these statements.

Page 129: Advanced KM Development

6.3 Discovery Pitfalls 121

6.3.2 Active determines what to execute

Some people think that only discovery keeps running and prediscoverycan only be executed once. This is not true. The value of active willdetermine what to execute and it is perfectly possible to have a KM thatwill only use prediscovery and never go to discovery at all.

Page 130: Advanced KM Development

122 Prediscovery and Discovery

Page 131: Advanced KM Development

Chapter 7

Instances

7.1 Why you need to create instances

When you develop a KM, you are writing an application managementtemplate. The application class is can be compared to a real object class.Just like with object oriented programming, you will create instances ofa class for each managed object.

When an application class is instantiated, each instance will showup with the menu commands and infobox commands as defined on theapplication class. At the same time all parameters that are defined onthe application class will be created under the instance as well. If theparameters were defined active, they will immediately be scheduled forexecution.

Before the first instance is created, the only code that will be exe-cuted on the agent for you application class is the prediscovery or dis-covery script1. This is again one of reasons why discovery is so special.

In order to create instances you should call the create() function. Itis also possible to create instances using the simple discovery rules, butwe will not cover that in this book because of the limited functionalityand control.

1This is not really true, setup commands are also executed only once for the applica-tion, but we already told you not to use them

123

Page 132: Advanced KM Development

124 Instances

7.2 The Create Function

The PSL create() function has the following syntax :create(sid,label,state,msg,parent);

sid : sid of the instance you create. This is the name you will have touse when you want to access this instance in the PATROL names-pace.

label : name (label) of the instance you create. This only applies tothe visual representation of the instance on the PATROL console.If you specify the empty string then the instance sid is used asthe label. The instance label can be changed at runtime (at theexpense of a network packet that will be send). Usually the valuesfor the sid and the label are the same if there is no real reasonto make them different. However, they don’t have to be the same.Don’t just expect them to be the same and always make sure torefer to the instances sid instead of its label.

state : initial state when created

msg : message for event (“” = default)

parent : instance sid for logical parent The parent of the instance is aninstance itself and should always be written as /APPL/INSTsid.You have to make sure the parent instance already exists beforeit is referenced, otherwise the child instance will not be parentedproperly.

Only the first argument is required, but you will have to specifythree arguments to create a proper instance. The last argument is usedfor creating nested instances and we will discuss that later in this chap-ter.

The label of the instance can be changed at run-time and the consolewill update the label of the instance immediately when it is changed onthe agent. This feature can be useful if you want to allow the user touse a different naming convention for the instances at runtime (label in-stances by hostname or by IP address). You should be aware that chang-ing the label introduces network traffic to notify the consoles about theupdate and the label should therefore not be changed without a goodreason.

Page 133: Advanced KM Development

7.2 The Create Function 125

ý ¼ÈÂþi-»È¼µÃ#ÆË÷Ç�Æ�»#i¡À�Äȼý ¼ÈÂþi-»È¼¯Ã#ÆË÷Ç�ÆÍ»#i¡À�ĵ¼ akaaka create()create()

ÿÿ rU�����u��s���u��������}��� ����r@������u���s��u�������p}����������

discoverydiscovery��parameterparameter�� ���������������! "�$#���������%�&���' "��#ÿÿ ( vUs*)+������Á}-,�././|�0%1�,�2�0Dy�z( v@s*)3�������}-,�.4.W|�051�,�2�0Dy�z

APPL_1

INST_A INST_B

P1 P2 P1 P2

APPL_2

INST_YINST_Xcreate(“ /APPL_2/INST_Y” ,” INST_Y” ,OK);

Slide 7.1: Instance Creation

When you are implementing the instance creation functionality ofyour KM you should know that end users expect a proper response fromyour KM. That means, if you allow users to add instances to the instancelist through a response() function, and they press OK, they expect tosee the icon (or an error message) after a short time. Waiting for thenext discovery cycle is usually unacceptable. Some developers thinkthat create() can only be done from within discovery. Nothing is furtherfrom the truth. The create() function can be called from within anyPSL script that runs on the agent. Usually the scripts that are used forcreating instances are :

Prediscovery and discovery : This is the classic way of creating in-stances. At least one of the KM’s in your KML will have to createinstances from discovery.

Parameters : Parameters that create instances are very useful whenthe collection of data may lead to creation of additional instances.For example a parameter that alarms on “problem users” might

Page 134: Advanced KM Development

126 Instances

as well maintain the list of instances in the “PROBLEM USER”application class.

Menu Commands : When a user explicitly asks to monitor a specificinstance, one might as well do the creation of that instance rightafter the user input has been validated. Usually the informationentered by the user is also stored in pconfig so the instances willbe recreated when the agent is restarted. If creation is initiatedfrom a menu command then you could consider moving the “ini-tial creation” of the instances to prediscovery to minize the codeexecuted by discovery.

Events : This method could be used by PEMAPI consoles that wouldlike to create instances. Also scripts using PatrolCli will eventu-ally be executed by the event subsystem.

The only script where it is unlikely to find a create() function are in-foboxes. Even the system output window can occasionaly be used todebug certain situations.

7.3 The Destroy Function

The counterpart of the create() function is the destroy() function. Justlike create(), destroy() can be called from anywhere in PSL. When youcall destroy() the instance you specify will immediately be destroyedand all parameters belonging to this instance will be destroyed as well.

In case of nested instances, destroying an parent instance will alsodestroy the child instances regardless of the application class they be-long to.

Page 135: Advanced KM Development

7.3 The Destroy Function 127

ý ¼ÈÂþi-»È¼µÃ#Æ ¾µÆÈÂþi1ÇÄeµÃþi¡À=Äȼý ¼ÈÂþi-»È¼¯Ã#Æ ¾µÆÈÂþiØÇÄe¯Ãþi¡À=Äȼ akaaka destroy()destroy()

66 798;:=<?>A@4BC:?>ADFE�DFG�HJI+KLD�GJD798C:M<?>A@?BC:4>AD�EJD�GJH�I3KNDFG�DOO

discoverydiscoveryOOparameterparameterOO P!QSRUT/VSWUP/P/XSRUYP!QSRUT4VSWUP!P4X�R�Y

66 Z$[\B;]^DFE�DFG�H`_Ja�a�b�c*d�_�eFcgfNhZ�[9BC]^DFE�DFG�H`_Ja�a�bFc*d�_Je�cgfLh

APPL_1

INST_A INST_B

P1 P2 P1 P2

APPL_2

INST_YINST_Xdestroy(“ /APPL_2/INST_Y” );

Slide 7.2: Instance destruction

When the last instance of an application is destroyed, the applicationicon will be removed from the console as well. Because the applicationicon is destroyed after the last instance is destroyed, it is a good practiceto always add new instances before you remove the old ones. If you firstremove old instances and this list happens to be the same as the currentlist of instances you have then the application icon will be removed onlyto be recreated after the first new instance is created.

You have to be especially careful when you have written a menu com-mand that allows a user to “destroy all instances of this application”. Inthat case you could get the list of currently created instances by call-ing get("instances");. However, if you just run over this list and calldestroy() for each of the instances, it is very likely that you will destroyyourself before you finish the list. In this case you have to make sure toremove yourself from the list and destroy yourself as the last instance.

Page 136: Advanced KM Development

128 Instances

7.4 Techniques for creating instances

Usually, developers start working on the create statements first, onlyto find out that adding instance destruction is a lot more difficult thanthey thought. In some cases the QA team or customers hit the problemthat instance destruction is not supported in the code and most of thetimes this means almost a full rewrite of the code for the developer.

At the basis of the problem lies the way KM development is usuallydone : first, make sure it works, then make sure it works well.

In this section we will discuss the common mistakes that are madeand how you can reorganize your code so your KM will work better fromthe start.

It is a good practice to make sure that for every create() functionyou write, you also have a destroy(). Just like a C-developer wouldprovide a free () for every malloc().

7.4.1 Classic Create Loop

Typically, after you will have finished your create() logic, the code isalready so big and sometimes so complex that it isn’t easy to add thedestroy() function. By adding destroy() logic, your code not only be-comes bigger and more complex, but performance also starts suffering.

For the following examples, we assume you have a way to get a listof instances you want to create. The variable wanted instances will beinitialize with is newline seperated list.

In many KMs, you will see code that looks like this:

# Get the list of instances we would like to have2 # subsitute the ... with a command that will this list

wanted instances = ...;4

foreach instance (wanted instances)6 {

# Before we create the instance we should check if it wasn’t8 # created before

if (! exists(instance))10 {

create(instance,instance,OK);12 }

}

Page 137: Advanced KM Development

7.4 Techniques for creating instances 129

Listing 7.1: Typical create loop tabsize

This code works fine, but it checks every instance to see whetherit still needs to be created. Performance of the code depends on thenumber of instances; therefore, in the example, the more instances youhave, the more CPU is consumed. Even if all instance have been createdalready, the code will check for the existence of every instance.

7.4.2 Classic Destruction Loop

If you add a destruction logic to the following code, you will soon findout that this is not so easy as it may seem.

# This is the typical destruction loop2 current instances=get("instances");

4 foreach instance (current instances){

6 # We have to keep a flag to check if the instance# already exists or not

8 found=0;

10 # Now run over each instance and check for existanceforeach good instance (wanted instances)

12 {if ( instance == good instance)

14 {# If instance was found, set the flag and exit

16 found=1;last;

18 }}

20

# If this is not an instance we want (therefore not found),22 # destroy it

if ( found == 0)24 {

# This means an instance is in the current instance26 # list but not found in the wanted instances

Page 138: Advanced KM Development

130 Instances

destroy (instance);28 }

}

Listing 7.2: Typical destruction loop tabsize

In the code above, destruction logic was added to the create-loop.Usually you will see that the wanted instances list will be more or lessstatic (give or take a few instances). By looking a bit deeper on how thiscode affects performance, we can come up with the following formula :

number of checks = current instances∗(current instances+1)

When your KM contains 50 instances, this would mean almost 2500if-statements for every discovery cycle. The result of these checks is verylikely to be nothing (in case the wanted instances list didn’t change)

7.4.3 Optimizing the Create process

Take a look at the following code and notice the use of the difference()function.

# Get the list of instances we would like to have2 # subsitute the ... with a command that will this list

wanted instances = ...;4

# Get the list of the current instance from the namespace6 current instances=get("instances");

8 # To find out which instances should be created, we use the PSL# difference function

10 to create=difference(wanted instances,current instances);

12 # This same function can be used to find the instances that should be# destroyed.

14 # Read this as : What we currently have but don’t wantto destroy=difference(current instances,wanted instances);

16

# Now create the instances18 foreach instance (to create)

{20 create(instance,instance,OK);

Page 139: Advanced KM Development

7.4 Techniques for creating instances 131

}22

# And destroy the instances we don’t need anymore24 foreach instance (to destroy)

{26 destroy(instance);

}

Listing 7.3: Optimizing discovery tabsize

This code does the same as the previous example but a lot faster.The foreach loop for the create and the destroy logic is only called whensomething needs to be done. Additionally, the very fast (and readable)difference() function is used instead of the slower foreach() loops.

For each additional instance, some extra CPU will be necessary forthe difference() call, but that extra cost is compared to the extra priceyou would pay in the first example. Besides that you will not need to doneedless checks in case no instances have been added or removed fromthe wanted instances list.

7.4.4 Create Return Code Checking

It is a good practice in every programming language to check for thereturn code of the functions you use. Most of the times, the return codeof the create function is not checked, although PATROL administratorslike KM’s that do check the return code.

# Get the list of instances we would like to have2 # subsitute the ... with a command that will this list

wanted instances = ...;4

# Get the list of the current instance from the namespace6 current instances=get("instances");

8 # To find out which instances should be created, we use the PSL# difference function

10 to create=difference(wanted instances,current instances);

12 # Now create the instancesforeach instance (to create)

14 {

Page 140: Advanced KM Development

132 Instances

create(instance,instance,OK);16

# Let’s presume we want to set some instance specific data18 set(instance."/mydata",somedata);

}

Listing 7.4: Problem when not checking return code of create tabsize

This code look fine, but if the instance is filtered by specifying itin the /AgentSetup/<APPL>.filterlist configuration variable, the createstatement will fail. (More details about this variable later.)

If you didn’t cater for this situation, then in the second foreach state-ment, the set will fail and generate a run-time error. Therefore, it isbetter to ensure that create was successful, as demonstrated in the codebelow.

# Get the list of instances we would like to have2 # subsitute the ... with a command that will this list

wanted instances = ...;4

# Get the list of the current instance from the namespace6 current instances=get("instances");

8 # To find out which instances should be created, we use the PSL# difference function

10 to create=difference(wanted instances,current instances);

12 # Now create the instancesforeach instance (to create)

14 {if ( create(instance,instance,OK))

16 {# Now we can safely set the instance specific data

18 set(instance."/mydata",somedata);}

20 }

Listing 7.5: With create return code checking tabsize

Another way to prevent these types of error from occuring is by re-checking the current instance list after all creates have been done. This

Page 141: Advanced KM Development

7.4 Techniques for creating instances 133

is specifically useful when executed from within discovery and the dis-covery process also acts as a collector for each of the instance. In thiscase it might be a good idea to split the collection logic from the createlogic, as shown in the following code:

wanted instances = ...;2 current instances=get("instances");

to create=difference(wanted instances,current instances);4

# Now create the instances6 foreach instance (to create){

8 create(instance,instance,OK);}

10

# Create might have failed, but since we want to set data12 # for every instance we have anyway, just requery the ”instances”

# attribute14 current instances=get("instances");

16 # Now we can be pretty sure the instances existforeach instance (current instances)

18 {set(instance."/Status/value",...);

20 }

22 # NOTE : for the super defensive programmers actually after requerying# you can’t be sure the instances will exist .

24 # Nothing prevents someone from destroying an instance while you are# running in that set−loop. If you really want to be sure you must

26 # check for existence before every set call . And even then there is a# theoretical moment that you will try to set something that has already

28 # been destroyed.

Listing 7.6: Alternative to checking each return code tabsize

Page 142: Advanced KM Development

134 Instances

7.4.5 File Check

In some cases, discovery is completely dependent on the content of a file.Because of this dependency, the file will occasionally need to be parsedto find the wanted instances list.

A good way to accomplish this is to determine whether the file hasbeen changed. If the file has changed, you can parse it and see whetheryou need to add or destroy instances, as shown in the following samplecode.

# get the current timestamp of the file we want to check2 timestamp = file(file to check);

4 # Retrieve the timestamp from the namespace. The first time this executes# it will be set to ””

6 old timestamp=get("old_timestamp");

8 # Process only if the file has changedif ( timestamp != old timestamp)

10 {# File has changed

12 # Make sure to save the new timestampset("old_timestamp",timestamp);

14

# Check if file exists16 if ( timestamp)

{18 # file exists

# now process the file and do your actual discovery20 do discovery();

}22 else

{24 # process ” file doesn’t exist ” ( anymore)

do file empty();26 }

}

Listing 7.7: With File Check tabsize

In this code the first time discovery runs, get("old_timestamp")

Page 143: Advanced KM Development

7.5 Create Icon for class 135

it returns NULL (and an invisible run-time error). That means thattimestamp and old timestamp will always be different unless the filedoes not exist. If that is the case, file () will return NULL and will bethe same as old timestamp, which does not present a problem becausethe file will not get processed if it doesn’t exist.

If the file has been processed, the timestamp will be saved. Thenthe discovery cycle will look for the old timestamp again and use thattimestamp to check whether the file changed.

7.4.6 Process Check

When discovery is dependent on the existence of processes, you can usethe full discovery() call which was already described in detail in theprevious chapter. An example is shown in the code below.

# Check if the process cache has been refreshed since the last2 # time this command executed

if (! full discovery())4 {

# If the process cache was not refreshed, exit6 exit;}

Listing 7.8: Checking for process cache updates tabsize

7.5 Create Icon for class

In the PATROL console, the application class can be made visible ifyou select the “Create Icon for Class” on the KM property sheet. Thisapplication icon will not have any extra functionality and will alwayshave the same name as the name of the KM. All instances that willbe created will the always have an application icon as a parent. Withnested instances, the application icon can be shown multiple times.

If you unselect the create icon for class then the console will not showa class icon as a parent to each instance. Selecting or unselecting thistoggle is only a visual effect and doesn’t change anything in the way thenamespace works.

If the check box is not checked then the application icon will not becreated.

Page 144: Advanced KM Development

136 Instances

create(“ /APPL_B/X” ,” root” ,” OK” ,” ” ,” /APPL_A/INST_1” );

root var

create(“ /APPL_B/Y” ,” var” ,” OK” ,” ” ,” /APPL_A/INST_1” );APPL_A

INST_1 INST_2

ijilk�m�n�oqp�mqrts9uviwixly zJ{}|C~�y {���~���xl� k�� �}{�y �4� ���

etc

create(“ /APPL_B/Z” ,” etc” ,” OK” ,” ” ,” /APPL_A/INST_2” );

tmpcreate(“ /APPL_B/X” ,” tmp” ,” OK” ,” ” ,” /APPL_A/INST_2” );

���J���\�J�����J���\���J�J������J���\�J�����J���9�L�J�J������ �C�c`��J���/�%_\���J�\� � ��`����?`b_��L�������L���� �C�c`��J���/�%_\���J�\� � ��`����G`d_����������L�

Slide 7.3: Nested Instances without icon for class

  _\���J�9�¡���a`��£¢%��¤J�L¥¡¦����J§  _\�J���9�¡���a`��£¢%��¤J�L¥¡¦����J§

¨ª© «t¬�­qpjmqoq«tm�© ­q®9¯�rt®9pl­vu oq°v°¨A© «±¬9®9s9«9­qpjmqoq«±m'© ­q®9¯�rt®²pl­qu ov°q°

Slide 7.4: Example for create Icon for class

Page 145: Advanced KM Development

7.6 Nested Instances 137

7.6 Nested Instances

Nested instances are just a visual feature of the console, there is no ad-ditional object level introduced in the Agent tree. This is the most im-portant thing to understanding nested instances. Although instanceswill appear on the console as if there is a parent-child relationship, thePATROL namespace doesn’t change. There are some ways to nest in-stances. If you don’t remember the proper syntax of the create state-ment take another look at the beginning of this chapter before contin-ueing.

When creating nested instances you have ensure that the instancesids for a certain application class are unique. This is sometimes over-looked, because the instances could appear under a different parent.

³³ ´;µ?¶g·!8�¸;¹j¶gµ?8Cº�»�>98;·Sµ?¼9>�½´Cµ4¶g·/8¾¸C¹j¶gµ?8;º�»�>98C·Sµ4¼\>�½³³ create(inst,create(inst,lbllbl,state,,state,msgmsg,parent);,parent);

¿¿ Ñ���Í¡Î?ÀÑ���Í¡Î4Àsidsid ÁàΪÒ�Ì©Ñ���͡Ϊ�U��×)Ì4Ä Á Ôp×)ÏDÌ)��Î8ÌÁÅ Î8Ò�Ì]Ñ���Í¡Î8����×)Ì4Ä Á Ô�×)Ï)Ì)�UΪÌ

¿¿ ÕÇÆ�ÕÕÇÆ�Õ À6����Ó�Ì Ú Õ��ÃÆ�ÌDÕ�Þ ÁÅ ΪÒ�Ì]Ñ��<ÍaÎ8�U��×DÌ!Ä Á Ôp×)Ï)Ì)�UΪÌÀ6�<�_Ó�Ì Ú Õ��ÅÆ�Ì)Õ�Þ ÁàΪÒ�Ì©Ñ���͡Ϊ�@��×)Ì/Ä Á Ô�×)Ï)ÌD��Î8Ì¿¿ Í¡Î8��Î8Ì�À@Ñ���Ñ�ΪÑ��UÕ�ÍdΪ�UΪÌWÐ�Ò�Ì)�p×)Ï)Ì)�@ΪÌDÖ͡Ϊ�UΪÌ�À@Ñ���Ñ�Î8Ñ���Õ_Í¡Î8��Î8Ì©ÐKÒ�Ì)��×)Ï)ÌD�UÎ8Ì)Ö¿¿ Ó�ÍaÝÓ�Í¡Ý À�Ó�Ì)Í¡Í¡��ÝUÌ ÂwÁ Ï©Ì)ØUÌ)��Î ÚwÈÅÉ�Ê Ö�Ì Â �UÔ�Õ�ΪÞÀ_Ó�ÌDÍaÍ¡�UÝ�Ì ÂjÁ Ï]Ì)ØUÌ)��Î ÚwÈÅÉ�Ê Ö�Ì Â ��Ô�Õ�Î8Þ¿¿ Ë �UÏ)Ì)��Î?ÀUÑ���͡Ϊ�U��×)ÌË ��ÏDÌ)��Î4ÀUÑ���͡Ϊ�U��×)Ì Í¡Ñ�ÖÍ¡Ñ�Ö ÂwÁ Ï©Õ Á Ý�Ñ�×D��Õ Ë �UÏ)Ì)��ÎÂjÁ Ï]Õ Á ÝUÑ�×)��Õ Ë ��ÏDÌ)��ÎÌÌ Í�Î ÏÐÍ$Ñ%ÒlÓ�Ô\Õ}ÖÅÖ\×9Ø5ÙjÔÅÚ±ÛÐÜÃݲØÅÞÍSÎßÏÐÍ�Ñ%ÒlÓ$ÔÃÕ}ÖÃÖÃײØ$ÙjÔÃÚ±ÛÐÜÅݲØÃÞ

Slide 7.5: Create syntax for nested instances

In the example on the slide below, we attempt to create four in-stances in the APPL B application class. The first and fourth createstatements are trying to create the instance with the same sid ’X’. The

Page 146: Advanced KM Development

138 Instances

first create statement creates the instance object with sid ’X’ and givesthe instance icon a label of ’root’. PATROL knows this object by sid (’X’)not ”root”. The fourth create statement is requesting to create the in-stance object X a second time but with a label of ’tmp’. Even though thelabels are different we are attempting to create multiple copies of aninstance inside of an application class. This is not possible.

APPL_A

INST_1 INST_2

create(“ /APPL_B/X” ,” root” ,” OK” ,” ” ,” /APPL_A/INST_1” );

var

APPL_B

root

àáà�â}ãåä�æ*çSã*èjé;ê*àáà

ë?ì�í¾î�ï/ð ìÇî�ñ�ðNò}ëôó â�õ òÐî'ìÇöJò õL÷

tmp

create(“ /APPL_B/X” ,” tmp” ,” OK” ,” ” ,” /APPL_A/INST_2” );

APPL_B

etc

create(“ /APPL_B/Z” ,” etc” ,” OK” ,” ” ,” /APPL_A/INST_2” );

create(“ /APPL_B/Y” ,” var” ,” OK” ,” ” ,” /APPL_A/INST_1” );

Slide 7.6: Nested Instances creation (icon for class)

7.6.1 Main Map Instances

The special parent instance named "/" and be used as the fifth argu-ment (parent) in a create() function. This will place the instance onthe main map besides other computers. This is very useful if your KMmonitors a computer as a proxy, or if you are monitoring network com-ponents. More or less everything that doesn’t really belong under thecomputer can go there. You have to be aware that although this looksgood, some operators dislike this approach because they loose the feel-ing over “which host is responsible for what”.

Page 147: Advanced KM Development

7.7 Limiting the Number of Instances 139

Note: It is not possible to nest instances from different agents under aspecific main-map instance

7.6.2 Dummy application class instances

One of the tricks you can use to get the visual effect of nesting by cre-ating an application class with no parameters, menu commands and in-foboxes. This class can be as simple as a definition of icons for the class,setting active to 2 in prediscovery and exiting immediately in discovery.

Whenever another KM needs a parent, it can instantiate this dummyKM (even with different icons) and then nest itself under this parent.Be aware however, that the parent instance must already exist whenyou create nested instances.

Typically application classes that serve the only purpose of being aparent have a KM name of <XXX> CONT.

By creating such an application class you can also mimic the “CreateIcon for Class” behaviour, but still have a nicer label for the icon.

7.6.3 Determining the parent

To determine the parent instance name of an instance, you have thespecial built-in instance attribute parentInstance.

To determine children of an instance you must get all the instancesof the application (using the instances attribute) and loop through theinstances list comparing them to the parentInstance variable for matches.

7.7 Limiting the Number of Instances

When building a KM, it is always important to think about the conse-quences that it will have on the host OS.

It is not always easy to find relations between PSL code and CPU ofthe agent, but it is pretty easy to see that the agent’s footprint (memory,CPU) will be directly related to the number of applications, instances,and parameters.

Limiting the number of application classes will have a limited im-pact on the Agents CPU. The application class itself uses some memoryand CPU (Prediscovery/Discovery).

But it really starts getting important when you start instantiating.This can be easily demonstrated by the following example.

Let’s assume that you have four nested KMs :

Page 148: Advanced KM Development

140 Instances

• KM1 has 15 instances.

• When you click an instance of KM1, you see 15 instances of KM2.

• When you click an instance of KM2, you see 15 instances of KM3.

• When you click on an instance of KM3, you see 15 instances ofKM4.

• KM4 has two standard parameters each with a scheduling intervalof 1 minute.

• All the other KMs do not have any parameters.

What is the total number of parameters that will execute everysecond?

• KM1: 15 instances

• KM2: 225 instances

• KM3: 3375 instances

• KM4: 50625 instances

• Total instances: 54,240 instances

• Total parameters: 101,250 parameters every minute

• Parameters per second : 1687

Based on this example, you can see that it is important to limit thenumber of instances, especially when you have nested instances, be-cause it won’t be obvious to see the total amount of instances right awayon the console.

If you could rewrite the KM logic so you would be able to remove anapplication class (and a level of nesting), the results would be 15 timesbetter. If you could limit the number of instances create per KM byhalf, your KM would also be 15 times better. Those are very significantdifferences!

Page 149: Advanced KM Development

7.8 Limitations 141

7.8 Limitations

Once a nested instance has been created under a specific parent, itis impossible to change the parent of the instance. The only way toworkaround this limitation is by destroying and recreating the instanceunder a new parent.

Inheritance of a number of attributes does not follow the hierarchicalpath of its parent. Usually when you get() a variable from the names-pace and the variable is unknown, the namespace will be traversed,looking for the variable. A nested instance will not traverse its waythrough the parent.

Events generated from a nested child do not contain the full logicalpath of the instance. If this logical path is really necessary you will haveto retrieve the full path of the instance yourself and trigger one of yourown events. We will discuss events in detail in a later section.

7.9 Instance creation pitfalls

7.9.1 Limit number of nesting levels

Once you find out how to do nesting, you should still be careful not to usethe feature too much. Everytime you introduce nesting, you are askingthe operator for an extra mouseclick. Don’t just nest because you knowhow to do it, but do it because it adds value to the KM.

7.9.2 Characters you should not use

Don’t start the label with a ’:’. When a sid starts with a colon, the consoleexpects an icon name. Of course when you want to specify an differenticon than the one you defined in the application class, you will have tostart the label with a ’:’.

Avoid using ’.’ and ’|’ in your sid. The dot character is used byPEMAPI as a delimiter. The bar character is used by the layout databasein the console. Never use the ’/’ character in the sid, since this is thenamespace delimiter.

Page 150: Advanced KM Development

142 Instances

7.10 Creating invisible instances

If you create an instance of an application and you specify only 1 argu-ment to the create() function, then the instance will be created hidden.If you want to properly create an instance, you should at least providethree arguments to the create() function.

The arguments to the PSL create function are instance name, in-stance label, and initial status. A common error in learning PSL is totry one single argument as follows:

create("x"); # wrong!

This will create an instance, but it is hidden because the defaultstate in the absence of a 3rd argument is “NEW” which is an invisiblestate. The new instance will be created under the computer icon. Youwill have to drill down into a computer icon on each agent to see thenew icon.

7.11 Instance filtering

7.11.1 Adding Instance Filtering by Using Filterlist

As previously mentioned, it is possible to set the /AgentSetup/<APPL>.filterlistconfiguration variable to contain the instances you want to filter out.This setting is probably the cheapest way to do filtering when you de-velop your KM.

The /AgentSetup/<APPL>.filterTyoe works in tandem with the /A-gentSetup/[APPL].filterList configuration variable. Let’s presume youhave an application and it’s discovery contains this code :

for ( i=0; i< 10 ; i++){

name="inst_".int(i);if ( create(name,name,OK)){

print("Instance : ".name." create succeeded\n");}else{

print("Instance : ".name." create failed\n");}

Page 151: Advanced KM Development

7.11 Instance filtering 143

}

This will create 10 instances : inst 0 . . . inst 9Now, if you set

/AgentSetup/[APPL].filterList = "inst_1, inst_3, inst_5"/AgentSetup/[APPL].filterType = "exclude"

Then these three instances will not be created, but all the rest will.if you set

/AgentSetup/[APPL].filterList = "inst_1, inst_3, inst_5"/AgentSetup/[APPL].filterType = "include"

Then only these three instances will be created, all the rest will be sup-pressed. To implement filtering out an instance using a menu command,see below:

1. Create a new menu command titled Filter out this instance.

2. Add the following PSL code in the command area:

# Get our current application name from the namespace2 # This expects we are running on instance level (like in a menu command)

appl name = get("../name");4

# Now get the sid. This is not the same as the ”name”6 inst sid = get("sid");

8 # Apply the configurationpconfig("MERGE","/AgentSetup/".appl name.".filterlist", inst sid);

10

# Destroy our current instance. This will actually remove our12 # process as well and should therefore be executed as the last function

# in our PSL script14 destroy(".");

Listing 7.9: Changing the filterlist from PSL tabsize

3. This script will add the SID of the instance to the filter list andwill immediately destroy the instance.

Page 152: Advanced KM Development

144 Instances

When filtering out an instance, ensure you have a way to undo this.After you have filtered out all instances, you end up with nothing andthere might not be a way in your KM to add instances or edit the fil-terlist if non of the instances are available. To protect from this, add afunction in your KM that ensures an offline setup icon is created beforethe last instance is removed.

7.11.2 Filtering Suggestions

When you see you are creating too much instances, you should introducesome sort or filter capability for your KM. Here are some suggestions forfiltering criteria you could use :

7.11.3 Condition X

For example : Monitor only the top X instances.X could be a user defined criteria like bandwidth, %CPU, memory,

number of transactions or even combinations. Conditions could be TOP,LOW, HIGH, BETWEEN, ... This would allow the end-user to specifythe important criteria and at the same time would allow the end-userto remove the instances that are not interesting enough.

7.11.4 Show only NOT OK instances

This is really useful for user monitoring. The operator might not careabout a certain user unless there is a problem with that user. Thistype of monitoring is also called desired state monitoring, because onlyinstances of a certain state are shown. Don’t forget that “not ok” doesn’tnecessarily mean ALARM. For example a backup-connection that wentfrom offline to OK is probably an indication that something is wrong(why else would we have switched to backup mode).

7.11.5 Remove instead of filter

Sometimes instances have been historically created, and no one everhas bothered to remove them. If an instance is only showing up becauseit has always been this way, find out if it would make sense just remov-ing the instances. Maybe the data reported under the instance is onlyneeded as a reporting tool and history is even never user.

Page 153: Advanced KM Development

7.12 Instance Pittfalls 145

Consider moving the information in the parameters to a report thatcan be requested by executinhg a menu command. For our 4 KM exam-ple, this would mean to remove the parameters in KM4 (and KM4 alto-gether), but instead add a ”report” menu command that will return thedata the user would otherwise get by clicking on the parameters. Thiswould also change the collection of data from a “scheduled collection”to a “collect on request”. In KM3, you can then create some summaryparameters of the parameters previously shown under KM42.

7.11.6 Allow a configurable limit

In certain cases, it is a good idea to add a limit to the number of in-stances that will ever be created. This can be useful in situations whereyou can potentially end up in a runaway instance creation cycle. (In-stance are created because something is going wrong with the applica-tion).

7.12 Instance Pittfalls

7.12.1 Transient instance/history problem

When history expires, what happens to the data in the param.hist file?Let’s say you have a filesystem instance that exists for only a few mo-ments and is then unmounted or excluded. Would the history for theparameters of that instance persist in the history file forever? Doesdata ever get ”erased”? Can the history file go down in size?

You could think of the PATROL History database as a ”Circular”file, where the latest data is written, and the expired data is writtenover. The history database could increase in size if you added otherparameters/application classes or increased the retention period of anyof your parameters.

But then what about reducing the file size? The problem is that onewould like to achieve certain effects with custom KMs without blowingup the history file. This is proving rather difficult. For example, oc-casionally bringing in unique and temporary filesystems would slowlybring the size of the history file up. There would be no certain limit. Isthere a way to store history on continually changing instances without

2This example would reduce the footprint of the KM by roughly 95 percent.

Page 154: Advanced KM Development

146 Instances

having the history file run away ? This description of the problem iscommonly known as ”history pollution”.

There is a method you can use to work around this, but it might notbe acceptable for all cases. Let’s say you would like to monitor processesand display the combination of process name + PID and maintain somehistory about them.

This will be a very good example to get maximum history pollution,since the process name and PID is an extremely unique thing, and it’sunlikely that this combination will ever reoccur once the process hasdied.

It’s important to know that the history uses the combination of /AP-PL/SID/PARAM as an index to store the historical data.

What the end user will see is on the console is not the instance ID,but the instance label (which is the ”name” in the namespace), and thatis something we can use. Just think of an instance ID as a “slotnumber”and the instance label as the thing we want the end user to see. Appliedto our processes example, you could come up with something like this:

/APPL/SID =- /PROCESS/SLOT1- /PROCESS/SLOT2- /PROCESS/SLOT3

but the visible instance names would be

/APPL/INST=- /PROCESS/inetd-445- /PROCESS/ksh-336- /PROCESS/xterm-776

As long as the number of processes will be reasonable, we will notpollute the history more than necessary. (we will only create to numberof slots we need, and reclaim them whenever one becomes available)

Of course this feature might sound very good, but there is a problemwith this approach as well. If process A was using slot 1 and it dies, itbecomes available for a new discovered process, let’s say process B.

If we now ask for history of a parameter belonging to process B, wewill not only get the history from the B process, but also the old historyof the A process (or even every old process that occupied the slot in thepast). That means we have to provide addition info on the graph, so we

Page 155: Advanced KM Development

7.12 Instance Pittfalls 147

won’t confuse our end user what information he’s actually looking at.One way to do that would be to annotate every time a process occupiesslot and when it releases the slot.

Another way would be to define a certain ”impossible” value for eachof your parameters and set the parameter to this impossible value when-ever a switch occurs, or whenever no-one is occupying the slot.

Of course it would also be possible to use a combination of both meth-ods explained above. Maybe it would be better to go into the details ofhow the agent stores history.

The history file uses blocks to store data for parameter/instance val-ues. Over time, blocks are freed (because of history retention) for usewith new data, but the new space allocated will only be for values ofthe same parameter/instance. In other words, if you have an instance/FILESYSTEM/tempfs01 and store history on it, when the history ex-pires, there will be room allocated in param.hist for /FILESYSTEM/tempfs01(only) even if that instance does not exist anymore. There is currentlyno direct method in PSL to handle this problem.

This is certainly different than how most people think it works.Usually, one assumes that once the history for /CLASS1/INST1/PAR1was ”out of date” then the space it took was available for any other/CLASSx/INSTx/PARx to fill.

Actually it is quite logical that this is not the case. The history fileworks just like a database. It is indeed the case that whenever historyis outdated, the occupied space will become available again for other/CLASSx/INSTx/PARx values.

The problem lies somewhere else . . . when you set history reten-tion period to 7 days, that means the oldest datapoint for a certain/CLASSx/INSTx/PARx will not be removed from the history databaseif the timedifference between the oldest datapoint and the newest data-points is less than 7 days.

In case INSTx is reasonably unique (for example, ”PID-PROCESSNAME”combination), and the history retention period is 7 days... you will even-tually end up with a huge history file, because after the process goesaway, the history will remain.

Maybe another example is better : Let’s say we have a process thatrestarts every 2 days. That means every two days it will be assignedanother PID. The data in the history database will not be cleaned upuntil there are 7 days worth of history. That means the index and datain the history database will never be removed.

Best case scenario, the process continues to run and will ”only” oc-

Page 156: Advanced KM Development

148 Instances

cupy 7 days worth of data, since the history works like a round robindatabase data which is older than now-7days will be overwritten withnew data.

Whenver the process dies (and the instance is removed), your historydata will not be cleaned up, because the rule is to keep 7 days worth ofdata . . . so it’s sitting there and you can’t access it.

For most KM’s this is OK, for example a filesystem is unmounted,instance is removed, filesystem is remounted, instance is recreated, andthe ”old” data is still available.

However, with our example, it is very unlikely that the combinationPID-PROCESSNAME will ever reoccur... and your data will just besitting there.

Since no extra data is added, there is no reason for the agent toclean it up (as mentioned before, history will be cleaned when is thedelta between timevalues of old and new datapoints are greater thenthe history retention period).

Of course it doesn’t matter how many times/year the process restarts,it is important to know that the agent will store (and not necessarilyfree) data for each /CLASSx/INSTx/PARx combination. The only free-ing process that happens is either console triggered (developer consolecan call ”Clear History”), or automatically when the timerange of a pa-rameter exceeds the history retention period.

Page 157: Advanced KM Development

Chapter 8

Parameters and RecoveryActions

8.1 Parameters

Parameters allow you to gather and display metrics of an application.A typical KM defines a number of parameter scripts that collect variousmetrics. As soon as an applications instance is created, all the param-eter defined in the application class will automatically be instanciatedas well. Parameters that have scripts defined will be put in the RUNQand will be scheduled by the scheduler.

There are three types of types of parameters (standard, collector andconsumer) each with different characteristics. The mandatory proper-ties of a parameter are

name : The parameter name will identify the parameter in the names-pace. Once the name has been defined, it can’t be changed withthe developer console anymore. If you really need the change thename of a parameter and don’t want to duplicate it manually, youcould edit the KM file with a text editor outside of the developerconsole. Once the KM has been modified in such a way, you shouldrestart the developer console for the changes to take effect.

active : This toggle allows you the create parameters which are inac-tive by default. Usually you will only create active parameters.The active flag is frequently used by customers who are not inter-ested to see the parameter in the console.

149

Page 158: Advanced KM Development

150 Parameters and Recovery Actions

help : These fields allow you to enter the help context ID and the helpfile. The help context ID has to be numeric (remember this whenyou are writing your Windows help files, because Windows alsosupports string context ID’s). The help file, should contain a file-name without path information.

type : The parameter type can be either standard, collector or con-sumer.

Besides these mandatory properties, there are also properties thatyou will only be able to enter, depending on the parameter type you areusing. The properties can be divided in two categories, execution andvisualization. Depending on the type of parameter you are defining, youmay or may not be able to enter information for the following properties:

execution information : Parameters that are responsible for collect-ing data will have to execute scripts to gather the data. If yourparameter will execute a script, you will be able to enter the fol-lowing information:

command type : Only command types that are defined on thisapplication level or computer class level will be visible (andusable). By default the command types ’OS’ and ’PSL’ willalways be there.

environment : You can specify OS environment variables youwant to add to the environment. The environment variable’svalue can contain %-macro’s like for example %{/hostname}.

command : The actual command to execute.

credentials : You could hardcode OS credentials here, but is itvery unwise to do so, because this would force you to modifythe KM whenever the username or password of an applicationchanges. Later we will discuss ways that will allow you todynamically set these credentials.

scheduling information : Defines when the execution shouldrun. This scheduler information instructs the agent when aPSL process should be created. Sometimes this leads to con-fusion : If you instruct the agent to start your process at 1:00PM and the agent was down at that moment, but starts up at1:05 PM, it doesn’t know it should start the execution.

Page 159: Advanced KM Development

8.1 Parameters 151

visualization and actions : Parameters that are responsible for visu-alizing data or executing recovery actions will have to define howthe data should be shown an when and alarm should be triggered.You will be able to enter the following information:

alarm ranges and recovery actions : Defines conditions to checkand actions to take when a new value for a parameter is ob-tained.

output type and attributes : Defines how the parameter shouldbe displayed on the console. It is also possible to specify a ’no-output’ display type, which will suppress the creation of theicon. Depending on the output type you will be able to specifyadditional attributes like title (except ’no-output’ type) andunits (except ’no-output’ and text type).

history : Defines how many days of history should be kept whenstoring values for this parameter. This setting can be overrid-den by changing the namespace variable historyLength forthis parameter.

Page 160: Advanced KM Development

152 Parameters and Recovery Actions

øAù ú?û$üþý4ú4ÿ��������û����� ��?û�� ú���� ��ÿ��

CollectorConsumer StandardType

Property

� ûwú������ lú4ù��������������������� � ��ÿ"!#4û$�%���

Security

Scheduling

øAùtü ý�ÿ����, Recoø&'� � ��ÿ��)(�*+� ��,��û��

Slide 8.1: Different Parameter Types

8.1.1 Standard Parameters

The standard parameter is the most complete of the three types of pa-rameters. This parameter offers both collection and visualization.

Non-PSL command type scripts will set the parameters value withthe data returned on standard output. Ensure that you return only onevalue if your parameter type is not text.

If you are using PSL, the standard parameter can act as a collectoras well. Actually you could say that the standard parameter will thenbehave like a collector with visualization build in.

Even turning a very important collector to a standard parametercould be beneficial. In this case the value of the standard parametercould contain an indication of the collection status.

If you set the output to something other than no output, you canupdate the parameter directly from the PATROL Console.

Note: A no-output standard parameter is not the same as a collector,

Page 161: Advanced KM Development

8.1 Parameters 153

standard has history and alarm ranges and can execute recoveryactions

- �\���J�=�'_\� ¦J�%_\�L¥����\�%_����J�%_\�J���9�%_ � �J� � ���- �9�L�J�=�'_\� ¦J�%_\�L¥����\�%_����J�%_\�J���²�'_ � �J� � �J�.0/21)3547698:8<;91)=?>$39@)A"BC6'D7E�F

GG H <?49I�J�KMLH <?49I�J�KML stdoutstdout >�8=4�>�N?p OQP?FSR%TD8VU>�8=4�>�N?p OQP?FSR%TD8VUGG I�J�KML?>à8=4�IWNSP?FSR%TD8VUSX�p�p�p�J YI�J�KML?>à8=4�IWNSP?FSR%TD8VUSX�p�p�p�J Y.0Z\[]_^�F`A7>a69>$b)AcD"d';'e,f�A7F2g�4c6'e,e,A747>Q69D7hGG 8=f?FG7�C�RU8iLSR 5%jD8;:=<SRkRU8=:�46<?gml�5U4Wn#:=<SRkRU8�:=465 <?H#>à46F?4WTD>8=f?F�79C�R 8oLSR 5%jD8;:=<SRkRU8�:=46<?gml�5U4Wn#:=<SRkRU8�:=465 <?H#>à46F?4WTD>.0p2@)=);9>$A7;1.�e,A"q$Dc698srtpCu

Slide 8.2: Standard Parameter

8.1.2 Consumer

A consumer parameter only implements the visualization and recoveryactions.

The most challenging issue with a consumer parameter is that youcan’t determine which parameter, menu command, or discovery scriptsets the consumer. Therefore, you should document where the settingof the parameter occurs.

Page 162: Advanced KM Development

154 Parameters and Recovery Actions

  `����L�=¥ �%_�¦J�%_9�L¥����9�%_����J�%_\�J���\�'_ � �J� � �J�  `��J�L�=¥ �%_�¦J�%_9�L¥��J�\�%_����J�%_\�J���\�'_ � �J� � �J�v?wcx�y�F�>$A71�F`z5>$6547{�;91)|'A}y,1~wc�';9x,��A7z5;9>$>$Dcy�.��)>�Av01�6�FV47{)A7=)�)x�y,1�|v01�69>a�)@)=);9>$Ac;1.)x�A�g�1)6�FV4�Dcy,@)>$F`hv01�6·.);947E�BC;9D7=?DcA7q�A7DcAc1)47A7F2g�BC{)65F`A7>�g�h�8�A��chv*)���F�>Ü.)A}BCA7x,x�=�6'47�)8:A71�>�A7=

Slide 8.3: Consumer parameter

Page 163: Advanced KM Development

8.2 Parameter Styles 155

8.1.3 Collector

A consumer parameter only implements execution of scripts.You should only use the PSL command type when defining a col-

lector. If you use another command type, stdout will implicitly set thevalue attribute of the parameter, but since a collector doesn’t have avalue attribute, you will get a run-time error.

  `��%���J���?`b_�¦J�%_\�L¥����\�%_����J�%_\�J���9�%_ � �J� � ���  `��%���J���?`b_�¦J�%_\�L¥����\�%_����J�%_\�J���²�'_ � �J� � �J��?�t�2�\�������47698�8<;91)=?>�3'@)A

�� � F?>�HD<��S�?Fc�%�D8��jF?464�g=5k���D4�8� F?>�HD<��S�GFS�%�D8��jF?464�g=5k���D4�8�� � F?H#>à8=4AF��U<?4A<?B1<?4WnD8=gm�S�GFS�%�D8� �>$�� F?H#>à8=4AF��U<?4A<?B1<?4WnD8=gm�S�GFS�%�D8� �>$��0�269>a=)¡,DcA747>$¢,35£)@)=);9>QAc;1.)¢�A

�� CDF?g=F?7a8=4�8=g�>�l�5U4,nD<c�D4�5 :=<?HD>�7�8=H��#:�<G7�7aF?H�¤CDF?g=FG7�8=4�8=g�>�l�5U4,nD<c�D4A5U:=<?HD>�7�8=H��#:�<G7�7aF?H�¤

Slide 8.4: Collector parameter

8.2 Parameter Styles

There are several parameter styles to choose from. As listed above, notall parameter type support all styles. A definition of each parameterstyle and its meaning is given below.

8.2.1 Text Parameters

The text parameter is the only parameter that does not store history,but “No history” does not mean “no memory”. The value of the text pa-rameter is stored in the agent’s memory. The more text you store inthe parameter, the bigger the agent will become, so you have to be very

Page 164: Advanced KM Development

156 Parameters and Recovery Actions

careful if you type commands like this :set("value",get("value").new info);

These cumulative parameters, have a risk consuming a great dealof memory. For the same reason, you should not use text parametersfor displaying entire log files. If you really want to show something ofthe log, you could decide to only show the new log entries since the lastcollection cicle.

You cannot define alarm ranges on a text parameter1, but you canchange the state of the text parameter by changing the status attributelike this : set("status",AlARM);.

Because you can’t define alarm ranges on a text parameter, it willbe impossible to execute recovery actions as well. If you really want toexecute recovery actions, you will have to do it in the collection cycle orby creating a parameter that allows you to execute the recovery actions.

¥¥ ¦�§�¨¦�§�¨onlyonly ©�ª«¬ª�­ ¨¬®$¨ «o¯2° ®$§�±�²�®)§ °�³ ®´± «¬µ©�ª«¬ª�­ ¨¬®$¨ «o¯2° ®$§�±�²�®)§ °�³ ®´± «¬µ¥¥ ¶t· ª«¬­¸«¬ª�¹�º ¨ ³}»�¼ ¨S½¬±¾¨ «¬µCª ½S® ° ± ¹�³¶t· ª«¬­¸«¬ª�¹�º ¨ ³}»¿¼ ¨S½¬±¾¨ «¬µCª ½S® ° ± ¹�³

¹ ±�® © ± ³�³�°�À ·�¨0Á�² ³ ¨ ¹ ±¹ ±�® © ± ³�³�°�À ·�¨0Á�² ³ ¨ ¹ ±-- ±²�® © ²�®)½¬± ¹�³ ² ­ ¨ «CÂ�–²�® © ²�®)½S± ¹�³ ² ­ ¨ «CÂ�Œ¥ Ä ª�¹�À ¨ ³ ¨¬® °�¹�ª · ª«¬­ÆÅÇÅÄ ª�¹�À ¨ ³ ¨¬® °�¹�ª · ª«¬­ÆÅÇÅ

Slide 8.5: Text Parameters

1This is technically incorrect, you can define alarm ranges, but they will simply beignored.

Page 165: Advanced KM Development

8.2 Parameter Styles 157

8.2.2 No Output Parameters

Although no-output parameters don’t show up, you can use them tostore history. Even a consumer parameter can have a no-output type.

You can also define alarm ranges and recovery actions for no outputparameters. This can be very useful in case you want to execute some”hidden” recovery actions or if you want to increase the functionality ofparameters that can’t execute recovery actions (like a text parameter).

ÈÈ É�ʬË�Ì�ÍiÎ&ÏÑÐ�ÊSË�Ì�ÒÉ�ʬË�Ì�ÍiÎ&Ï�Ð ÊSË�Ì�ÒÈÈ Ó�Ô�Õ�Ì×ÖØÌ�Õ�Ù&Ú�Í�Ð�ÛÝÜ�Í�Þ�Ë�ß�Í�Ì�Ò~Õ�Þ�Ê�Ï�Ë�ÙmÐ�à�Ë�Ì�á�ÏÇâÓ�Ô�Õ�Ì×ÖØÌ�Õ�Ù&Ú�Í�Ð�ÛÝÜ�Í�Þ�Ë�ß�Í�Ì�Ò~Õ�Þ�ÊÑÏÑË�Ù&Ð\à�Ë�Ì�áãÏäâ

å ЬÍ�æçâ¬Ë�Ì�Ù å ÖèÍ�Ì�ÏVÞ�Õ�Ô+æ&Õ�ʬÕå ЬÍ�æçâ¬Ë�Ì�Ù å ÖèÍ�Ì�ÏVÞ�Õ�Ô+æ&Õ�ʬÕÈÈ é�Ë�ÙmÐ å Ö�Í�Ì�Ð"Þ�Õ�Ù?êiÍ�ë�ì:Ë?í å Ê�î å Ê ïé�Ë�ÙmÐ å Ö�Í�Ì�Ð"Þ�Õ�Ùçê\Í0ë�ì:Ëðí å Ê î å Ê�ï

Slide 8.6: No Output Parameters

Page 166: Advanced KM Development

158 Parameters and Recovery Actions

8.2.3 Gauge Parameters

A gauge parameter can only show a single value at a time. When anno-tated data is available, the Info button on the gauge will be activated.You can click the button to display the annotation data.

GaugesGaugesññ í�Ù�ÔäÒòÐ�ÎiË�àãÐ&Ô�Õ�Ð�Ê}ß�Õ�Ô å Í�ÛóÕ�ÔÑÕ�Ì×ÖôÌ�Õ�Ù&Ú�Í�Ðí�Ù�ÔäÒòÐ�ÎiË�àãÐ&Ô�Õ�Ð Ê}ß�Õ�Ô å Í�ÛóÕ�Ô�Õ�Ì×ÖôÌ�Õ�Ù&Ú�Í�Ð

Is clickable when«±¬9mqpwm�© °�oq¯9¯9®9«tov«tm`õdata

Slide 8.7: Gauge Parameters

Page 167: Advanced KM Development

8.2 Parameter Styles 159

8.2.4 Graph Parameters

Graph parameters provide the most flexibility. After opening them, youwill immediately get an overview of the status over time and the trendof the collected data. It is also possible to drag and drop graph typeparameters together so it will be displayed as a single graph. The graphtype can be changed to for example a pie or a bar.

Annotated data points will be marked with an asterisk.

GraphsGraphsöö Ð ÎiË�à�Ð÷Ê�ÏäÖèÍ\ÏÑÙ�ÊSÍ�Ì�ß�Õ�ÔÐ ÎiË�à�Ð÷Ê�ÏäÖèÍ\ÏÑÙ�ÊSÍ�Ì�ß�Õ�Ôöö Ð ÎiË�à�Ð}Õ�ÙaÙ&Ë�ÊSÕ�ÊSÍ�æÐ ÎiË�à�Ð}Õ�ÙaÙ&Ë�ÊSÕ�ÊSÍ�æ

datapointsdatapoints

Slide 8.8: Graph Parameters

Page 168: Advanced KM Development

160 Parameters and Recovery Actions

8.2.5 State Boolean Parameters

The boolean output type is not really true boolean, but more a tri-stateboolean. Although the output type suggests only true and false (1 and0, OK or not OK), this boolean respects all PATROL states (OK, WARN-ING and ALARM). The WARNING and ALARM state will be shown asa false sign, OK will be shown as OK.

øø É�ÎoË�àãÐ�í�ùûú#üýÓ:Ü"ìþú#Ó�ÿ�� Ð��cÕ������� à ��í�ùûú#ü��:Ütìûú���ÿ�� ����������� ������������������� �"!$#$%'&�($��)�*"+-,/.10324,15768&�($��)�9�������������������"� !$#$%'&�($��)�*"+-,/.10324,15768&�($��)�9�� :1;<!$#=&')�� !$#$��#>!$� ;?� @A&';B��;DCFEHG-0/����C�E:/;�!$#I&�)�� !$#>�J#>!$� ;?� @A&';B��;DCFEHGK01����C�E

OK¨ |ML�{�N�|MO9~

UNIXNT

¨ |ML}{�N�|MO9~OK

Slide 8.9: State Boolean Parameters

Page 169: Advanced KM Development

8.2 Parameter Styles 161

8.2.6 Stoplight Parameters

This output type behaves a bit bizarre on NT consoles earlier than 3.4since the stoplight on NT will only show the green or red light, and theplatter will display the actual difference in the state. A yellow platterindicates a WARNING state. If the stoplight is red and blinking, itindicates an ALARM state.

From a Unix console, the stoplight turns green for OK, yellow forWARNING, and red for ALARM. From PATROL v3.4 on the behaviouron the UNIX and NT console is the same.

PP QJRTS�UWVYX[Z]\�^`_�acbd\�_cegfhV$ikjAiklQJRTS�UWVYX[Z]\�^`_�acbd\�_cegfhV$ikjAiklmm ngo�pIqsrut?vwvux�ywzA{M|�ywz}z ~���� �ngo�pIqsrut?vwvux�ywzA{M|�ywz}z ~���� �

PP �=SA��RT��V�ikSA�u����=SA��RT��V$i�SA�u���DoubleclickDoubleclick iconicon

UNIXNT

OK¨ |M�}{���|M�9~ OK WARN ALM

Slide 8.10: Stoplight pre V3.4

Page 170: Advanced KM Development

162 Parameters and Recovery Actions

�� b��s�}VF�w�����Al������TS�Ub��s�}VF�w�����Al������TS�U

UNIXNT

OK WARNING ALARM

Slide 8.11: Stoplight post V3.4

8.3 ExtraFilesList Parameter

ExtraFilesList allows a KM developer to specify extra files which shouldbe committed to an agent when the KM is committed. Below are thesteps required to specify extra files

8.3.1 Creating an ExtraFilesList Parameter

From a Parameter Dialog Box:

1. Create a standard parameter called ExtraFilesList in the desiredKM. Do not change the scheduling information.

2. Deselect the [Active] checkbox so that the parameter is not active.

3. Add the list of files to be committed in the command text window.Each file should be specified on a separate line. A distinction canbe made between PSL library files and any other file that should besend by putting the keyword #EXTRA or #LIB before the filename.

Page 171: Advanced KM Development

8.4 Parameter History 163

The #LIB keyword should be used when you specify PSL libraries,although the lib keyword doesn’t really make a difference (yet).

The #EXTRA should be used for all non-library files.Files for both keywords will be unconditionally send during commit.

Note: File locations are relative to the local or global psl directory ($PA-TROL HOME/lib/psl). When the console attempts to find the spec-ified file, it always considers the local directory first. The files willend up on the agent in the same location relative to the global psldirectory, regardless of whether the file was taken from the localdirectory or the global directory.

You should start the line with a # character because the # charac-ter is used as the comment character by most shells and PSL. Thus, ifsomeone accidentally activates the ExtraFilesList parameter, it won’tcause a problem.

ExtraFilesList will only work with developer consoles, since it usesthe commit function. You should never specify big binary files in theExtraFilesList, because this can impact the network performance. It isalso impossible to commit different executables to different platforms.

8.4 Parameter History

Patrol stores historical values for parameters (except text parameters)in a binary history file local to the agent. The disk space used is approx-imately 8 bytes for value and timestamp. There is also a seperate indexfile with one index entry per parameter. You can turn off history collec-tion for a parameter by changing the setting from “inherited” to “local”and setting the number of days to “0”. Since PATROL uses the doubledatatype for storing values, you might experience incorrect result whenstoring values that exceed the storage size of a history value.

Annotations are stored in a seperate history database and uses diskspace approximately equal to the number of text characters.

You can extract the contents of this history via the dump hist utilityor the PSL dump hist() function.

8.5 Annotated Datapoints

If you would like to save textual data for a certain value, you can anno-tate the datapoint. The syntax for annotation is :

Page 172: Advanced KM Development

164 Parameters and Recovery Actions

annotate("<param path>","<fmt>","<data>",...);

The annotation data will be saved as long as the history of the pa-rameter.

When you annotate a datapoint, you will always annotate the lastvalue that was set(). Remember to set() before you annotate !

Annotating data doesn’t come for free. All the data you annotate willbe saved to disk. Make sure to not just annotate every datapoint withall new log-entries that were collected when monitoring a logfile. Anannotation point should be an exception because otherwise the operatorwon’t know where to look first.

AnnotatedAnnotated DatapointsDatapoints

�� �7�����¡ �¢�£¡¤I¥§¦�¨}©�£¡ªg¤�¢�¥§©�¦�©�¦g¤=«�¤�£¬¤�ªg�¬¢��¡£�7�����¡ �¢�£¡¤I¥§¦�¨}©�£¡ªg¤­¢�¥§©­¦g©�¦g¤=«�¤�£¬¤�ªg�®¢��¡£�� ¯�°7±³²T�7´3µ¯�°7±³²T�7´3µ

¶¶ ·�¸®¸®¹<º§·�º¼»"½¼¾�¿J·�À"·}ÁI»"º§»ÂÀ�¿J·�º Ã�ÄBÅ�¾·�¸®¸�¹�º§·<º§»"½¼¾�¿J·�À"·}ÁI»"º¼»"À�¿J·�º Ã�ÄBÅ�¾ fmtfmt ÄTÅ<¾�Æ®·�º¼·�ÄBÅ�Ç Ç ÈÄBÅ�¾�Æ®·�º¼·�ÄBÅ�Ç Ç Èfmtfmt ¹�É®º Ê˹�¸®Ì=͹�É®º Ê'¹�¸�ÌÎÍ“ %Text”“ %Text”“ %“ % InfoBoxInfoBoxÏ ½§»"·�мÃÏ ½§»"·�мà datalinedataline isis infoboxinfobox item)item)Ñ­Ò=Ó »"Ì�É®¹�¸®Ì�» Ï ½¼À"»"·�ÆT¹<¸ÂÔ Õ­ÈÑ­Ò=Ó »"Ì�É®¹�¸�ÌË» Ï ½¼À"»"·<Æ�¹<¸ÂÔ Õ­È

�� Ö1¥¼×�¢�©�£¡ØIÙ³�¬¢��¡¦�¢�¥§©�¦gÚA�¡£¡¥¼©­�Ö/¥§×�¢�©�£¡ØIÙ³�¬¢��¡¦�¢�¥§©�¦gÚA�¡£¡¥¼©­�

Slide 8.12: Annotated Datapoints

8.6 Alarm Ranges

Alarm ranges define the ranges in which the state of the parametershould be considered OK, WARNING or ALARM.

Page 173: Advanced KM Development

8.6 Alarm Ranges 165

8.6.1 Settings

There are three ALARM ranges, as listed below, each with a minimumand a maximum attribute. Both minimum and maximum can only bedefined as integers.

When a new value arrives, it is evaluated agains the ALARM rangerules like this :

Border : [−∞,min border[ and ]max border,∞]

Alarm1 : [min alarm1,max alarm1]

Alarm2 : [min alarm2,max alarm2]

Note: ]. . . ,. . . [ denotes an exclusive range and and [. . . ,. . . ] denotes aninclusive range

These attributes will have to meet the following rule :min border <= min alarm1 <= max alarm1 <=min alarm2 <= max alarm2 <= max border

That means border is exclusive, if the definition is ]0,100[ then 0is not part of the border range, but 100.1 is. Alarm1 and alarm2 areinclusive, so if the definition is [10,30], then 30 would be ALARM, but30.01 would not.

Page 174: Advanced KM Development

166 Parameters and Recovery Actions

Û+���ÝÜ;¥ Þ��L�Fß�� ���J�\� � ��ß=�Û+���ÝÜ;¥ Þ��L�Fß�� ���J�\� � �Fß��

àà á1¦�â¼ãIä�±7²�åTæ1åT糯á/¦�â§ãIä�±7²�åTæ1åT糯àà ±7©�£¬ªg¤�â¼â§ãI¥¼¦�è¡â§é�êk¥§ë��B¨�©�£?�7ìT�³ç7í[îIïK�7ìT�³çÎí[ð±7©�£¬ªg¤­â§â¼ã=¥¼¦�è¡â§é�êk¥§ë��B¨�©­£B�7ìT�7ç³í�î=ïK�7ìT�³çÎí[ðàà åT �è¡â§é�êk¥§ë��?¨�©­£TñTá/ç³ò7åTçåT �è¡â¼é�ê�¥§ë��?¨}©�£TñTá/ç7ò³åTç

| ußovpËóõô | ußovp�ó÷öBorder Border

{ ®9«9­q®­øÅmqpwm®ù=ú³ûýü

Slide 8.13: Alarm Range settings

Page 175: Advanced KM Development

8.7 Recovery Actions 167

8.6.2 Range Overlapping

In case max alarm1 = min alarm2, alarm1 will take the precedence.In the extreme case in where all values are the same. Alarm2 is com-

pletely overlapped and therefore useless. That means that one valuewill belong to alarm1 and any other value belongs to border.

- ¦���� � �L�FÞ�����ß�� - �J�\� � �Fß��- ¦���� � ����Þ�����ß�� - �J�\� � �Fß��¢�Þ�����ß=�ÿþ�� � Ü;���=¦J§¢�Þ�����ß=�ÿþ�� � Ü;����¦J§

�� ���§¤�£®ª��I¥���¨����w¥¼¦� �����k¥�������§¤�£®ª��I¥���¨�����w¥¼¦� �����k¥������ ���§¤�£®ª��I¥���¥¼¦� �����k¥����������¡¦�¦�©�¢M©����¡£��¼¤�«�«��¡����§¤�£®ª��I¥���¥¼¦� �����k¥����������¡¦�¦�©­¢ ©����¡£��¼¤�«�«��¡��� �T©�£¡���¡£?¤����7¤���� �¬ � �����k¥��>��T©�£¡���¡£?¤����7¤������¡ � ������¥��>�

| u ovp����Border Border

| ußovp����| u oÅp����| ußovp����| ußovp����| u ovp����| u oÅp����| u ovp����| ußovp����| ußovp���

Slide 8.14: Range Overlapping

8.7 Recovery Actions

Recovery actions arise from the combination of KM design and the agent.The recovery action is an agent-executed corrective action that is launchedonce a problem is detected, in order to attempt to correct it. Recoveryactions are automatic and do not require any user intervention.

Recovery actions can also have escalated multiple actions. A se-quence of recovery actions can be defined to attempt alternative solu-tions to an alarm. Recovery action can also be used to return to normaloperation if the problem is corrected.

When a new value is set, the agent will perform a range check (thisexplains why you don’t see something going into alarm immediately af-

Page 176: Advanced KM Development

168 Parameters and Recovery Actions

ter you modified the range, the agent will first have to collect a newvalue).

No matter what happens, there will only be one recovery action run-ning per parameter! No matter how often you switch between ranges.If there is a recovery action that should be executed (and no recoveryaction is running), the recovery action will fire off immediately. If therewas a recovery action running (even on another range), your recoveryaction will not execute.

Each range can have multiple recovery actions. The moment theagent changes range (NOT the same as a state change), he will restartprocessing the list of recovery actions from the top. If the range is stillthe same when a new value arrives, the agent will try to fire of the nextrecovery action in the list (as long as there is not another recovery actionrunning for that parameter).

�%���\�L�%� � ß����J� Þ����"!#�å�ÝÜ�$ Û��J� � !��J��%���\�L��� � ß����J� Þ����"!#� � Ü�$ Û��J� � !��J�

%% &7��'¡©�(��¡£*)=¤�'¬¢�¥§©­¦�+-,Ω�£�.g©�¦g�0/¼ª�132A��/¼ª546287T©�£¬���¬£&7��'¡©�(��¡£*)=¤�'¬¢�¥¼©�¦�+-,Ω�£�.g©�¦g�0/¼ª�132A��/¼ª546287T©�£¬���¬£99 :<;>=@?BA>CED�;>F�FHGIJ?@K>L MH?DNFOL�?@L�;JP�QSR:<;>=@?BA>CED�;>F�FNGIJ?@KEL MH?DNFOL�?@L�;JP�QSR -- TVU :XWTVU :XW -- ALM)ALM)YY Z\[ ]�^_] `Xabc^\dfe>`Xa@^\gc[ `�hJiEj�kc^\l gE`Xabc^_dfe>`�mZ\[ ]�^_] `Xabc^\dfe>`Xa@^\gc[ `�hJiEj�kc^\l gE`Xabc^_dfe>`�m

%% n7¤�¦po���q�+��¡�g¢�©I¢�q�¦��>2 ���¡¢q�¦��srn7¤�¦po���q�+��¬��¢�©I¢q�¦��t2 ���¡¢q�¦��sruwv ?txVyzDO;|{uwv ?�x}yfDO;|{99 Q~R�?@K>L ��G@�3P U��c���@��� xVG@A>;|y�A>G@K>;EF�F�;>FQ~R�?@K>L ��G@�3P U��c���@��� xVG@A>;|y�A>G@K>;EF�F�;>F99 T�U :NW�?@K>L �OGB�6P U���������� DO;EFOFNycAEG@K>;>F�F�;EFT�U :NW�?@K>L �OGB�3P U����p����� DO;EFOFNycAEG@K>;EF�F�;EF99 U���U : � ?@K>L ��GB�3P �-Q~:X� u : ��� ;>�@;>��D�;>F�FN� � �U���U : � ?@K>L �OG@�3P �-Q~:X� u : ��� ;>�@;E�|D�;>F�FN� � �

Slide 8.15: Intelligent Recovery Actions

8.7.1 Use Recovery Actions Intelligently

Recovery actions can’t only be used to recover from a problem, but shouldbe considered to prevent a problem from happening and prevent situa-tions that adversely affect availability or application throughput.

Page 177: Advanced KM Development

8.8 Pitfalls 169

8.7.2 Recovery Actions on Alarm1, Alarm2, and Border

A recovery action is defined for a range and not a certain state. The stateis merely an attribute of this range. This behaviour is most of the timesoverlooked and it seems to be taken for granted that you should notdefine a recovery action for an OK state. This is unfortunate, becauserecovery actions on OK states can be very useful. For example, you candefine a recovery action for an OK state that would allow more processesto connect to a certain service.

8.7.3 Can Be Used to Tune or Detune

You can define automatic recovery actions to correct problems indicatedby a parameter’s ALARM, WARNING, or border alarms or to take otherappropriate actions based on the parameter’s value. When a parame-ter changes to a triggering state, one or more recovery action commandscripts can be queued for execution, each according to its properties set-tings. Recovery actions can be set up to execute by increasing strengthof action. In addition, you can create recovery actions that determinethe corrective action to take based on other parameter values or dataavailable in the PATROL Agent namespace.

8.7.4 Debugging Recovery Actions

Debugging recovery actions is pretty much the same as with menu com-mands. Recovery Action only have processes when they are spawned.To debug a recovery action you need to load, compile and run within thePSL debugger (remember the wrong context) or use the PSL debuggerfunction within your recovery action (to keep context).

8.8 Pitfalls

8.8.1 Turn History Off If Not Needed

If it is very unlikely that a customer will ever use the history for one ofyour parameters, you should set the historyLength to zero. (Maybe youshould also reconsider is this parameter serves a purpose.)

Page 178: Advanced KM Development

170 Parameters and Recovery Actions

8.8.2 Set Scheduling to a Reasonable Interval

Out-of-the-box scheduling is set to 10 minutes. Ten minutes and greatermay be too much or too small. You should adjust the scheduling accord-ing to your needs.

8.8.3 Value attribute

You can’t set an object, you have to set an attribute of this object! Thefollowing instruction is therefore invalid and can cause a lot of confusion: set("/MYKM/myinst/param1",50);

þ �;�J� Ü���� Ü\�L¥��J�\� Ü����J�L�����þ �;�J� Ü���� Ü\�L¥��J�9��Ü����J���J���

�C� ;9D7;98<A7>�A7DcF�;'D7A};|��B0;93'F�AX�'A74X��>�A7=?@)AcD��,1�FV>$;91)47A���#���)D71?6� f �¡~��F�>Q69Dc3¢� a1�69>a1)A7A7=�A7=�ç�21)A}4c6����,Ac47>Q69D"4c;91?DcAc@~�W;'47A}8£�~�W>f�,@~�,A�¤SF`>$;91�=);9D7=S¥9F�ç�A7>aF`4X¡�A7=~�~���W1~¦5>Q6�; reasonable interval� Annotated datapoint D7A7Fc�,=)A�691ð=S�,F`E���#�&AX�9>a@�;9Dc;98<A7>$A7D7F�;9DcA}D7A7F*�,=)A71)>3�,1ð8<A�8<69D73

§§ ¨[¤�.���+f©�£¬�B¢ª���)¨[¤�.���+f©�£¬�B¢ª���)DON’tDON’t « £¡©�,�¤�¢M�¡¤�'�ªg�¡ ���'�©�¢�¥§©�¦�¬« £¡©�,�¤�¢M�¡¤�'�ªg�¡ ���'�©�¢�¥§©�¦�¬

�®­�;9E�A"Fc�)D7A}>�65FVA7>a>f¡)Ap¯9;|���)A�;9>�>$D��°S�)>$A§§ /<APPL>/<INST>/<PARM>/<APPL>/<INST>/<PARM>/value/value

Slide 8.16: Pitfalls

Page 179: Advanced KM Development

Chapter 9

Menu Commands andInfoboxes

9.1 Menu Commands

Menu commands allow developers to add adminstrative functions toKM’s. Usually menu commands are used for administration of the KM’sand the application the KM is managing. Menu commands will only beavailable on application instances.

When the operator select a menu command the menu command textwill be send the agent and scheduled for immediate execution. Beforethe agent can execute the script, it will first compile it.

A menu command can be executed as a task or command. We willdiscuss what the difference between a task and a command is.

9.2 Menu command pragma’s

9.2.1 Developer Console Only Commands

To make a command only available for a developer console, in the firstline of the command text, use the following instruction in your PSLscript :

"#%MODES% dev"The result is that the menu command will only be available via thedeveloper console and will not show up on the operator console.

171

Page 180: Advanced KM Development

172 Menu Commands and Infoboxes

9.2.2 Console side menu commands

If you add "#%MODES% local" to your menu command, the menu com-mand will be run by the console as an OS process. The console willspawn an OS interpreter child process and execute the command.

Some macro variables you can also use in state change actions areavailable to pass some context to your OS command (see chapter aboutevents).

9.2.3 %%{. . . } macro

This macro will ask for user input and subsitute the result in the menucommand text prior to sending it to the agent. Although it is useful fortesting, because it is a lot easier than defining a response() function,the use of this macro should not be used in production code.

The data entered by the user will be literally replaced. Inproperinput by the operator can result in compiler errors. It can also allowoperators to execute arbitrary PSL code on an agent.

±± ² �w³ ��´ wµ �w¶¢· ¹¸ � ´¡� -¸ ´º² �w³ ��´ Hµ �w¶¢· -¸ � ´¡� -¸ ´º»» ¼-½¿¾ C®ÀsÁÃÂ�½ÅÄ<Æ�ÇHÆ�È�ÉwÊ<Æ�˼-½¿¾ C®ÀsÁÃÂ�½ÅÄ<Æ�ÇwÆ�È�ÉwÊ<Æ�Ë

±± Ì -¸ � ´<�Í· �ÎÏÎ � ¸�Ð ��ÑD��·�ÒD�@Ó ¹¸Ì -¸ � ´<�Í· �ÎÏÎ � ¸�Ð ��ѳ��·�Ò?�BÓ ¹¸»» C"¢Ô�ÉwÕ�Õ�Öw×<ÄÍÉw×<È�ØC"¢Ô�ÉwÕ�Õ�Öw×<ÄÍÉw×<ÈOØ»» ¼-½¿¾ C®ÀsÁÃÂ�½ÅÈOÉHÔ�ÖHȼ-½¿¾ C®ÀsÁÃÂ�½ÅÈOÉHÔ�ÖHÈ

Slide 9.1: Menu Command Pragma’s

Page 181: Advanced KM Development

9.3 Command or Task execution 173

9.3 Command or Task execution

The difference in functionality between a command and a task is verylimited. Both commands will result in a process created and maintainedby the agent and injected in the RUNQ for immediate execution. Thesubtle difference between both is almost only a visual effect.

9.3.1 Command

When you define the menu command, you have to select if you wouldlike to execute is as a task or as a command. If you select command,then the PSL script is scheduled for execution just like a parameter.You have no control over the process once it is launched. Any outputthat is generated by the menu command will be send to the systemoutput window.

ÙÙ ÚÛÉpÊ<Ë�ÉHÔ�Æ�Ü@Ü�Ô�Éw×<ÝtË�ÉHÈJÖHÞ>Ý>Æ�ËVÈ�ÖHß<×<Ô�à�átÉHËVâ�ãOÈOÈOäÚÛÉpÊ<Ë�ÉHÔ�Æ�Ü@Ü�Ô�Éw×<ÝtË�ÉHÈJÖHÞ>Ý>Æ�ËVÈ�ÖHß<×<Ô�à�átÉHËVâ<ã�ÈOÈOäÙÙ ÉHß<ÝtÊ<ß<ÝSãO×ÍÜ@ØwÜ@Ý>Æ�ÕåÉHß<Ý>Ê8ß<Ý-æ�ãO×<Ä<ÉNæÉHß<ÝtÊ<ß<ÝSãO×ÍÜ@ØwÜBÝtÆ�ÕåÉHß<Ý>Ê8ß<Ý-æ�ãO×<Ä<ÉNæ

Slide 9.2: Menu Command : Execute as a command

Page 182: Advanced KM Development

174 Menu Commands and Infoboxes

9.3.2 Tasks

If the command is defined to execute as a task, a console object (textbox) will be created when the command is started. From this consoleobject you can choose decide to kill, suspend or restart the command.Ouput is directed to this task window on the console.

çç restar tablerestar tableçç seperateseperate ÉHß<ÝtÊ8ß<Ý-æ�ãO×<Ä<ÉNæÉHß<ÝtÊ8ß<Ý-æ�ãO×<Ä<ÉNæçç èHétÖHêBëÍìOê�ìO×<étÆ�Ë�ÖHÔ�étì�ÇHÆ�í5Éw×<È�Ø5îtÉHËIC"ÂèHétÖwê@ëÍìOê�ìO×<étÆ�Ë�ÖHÔ�étì�ÇHÆ�í�Éw×<È�Ø5îtÉHËIC®Â

cmdscmdsïï ð_ñ�ò3óð_ñ�ò�ócmdcmd ô õ@öcõ�÷�ø�ùOú6û�üþýcÿ0ÿ���� � ý������ô õ@öcõ�÷�ø�ùOú6û�üþýcÿ0ÿ���� � ý������

Slide 9.3: Menu Command : Execute as a task

9.4 Extending Computer Class Menu Commands

Sometimes you would like to add menu commands to a computer class(for example the ALL COMPUTERS KM). Since BMC is already ship-ping these files, you should not ship a modified version of the file thatcontains the menu commands you would like to add. Instead you shouldcreate an overlay KM.

The explanation below is one of the ways to create an overlay KM.This feature is not limited to just computer class KM’s and can some-times be useful if you want to add parameters to any existing KM with-out having to modify the original file.

An example to add menu commands to ALL COMPUTERS :

Page 183: Advanced KM Development

9.5 Infoboxes 175

1. Create a new computer class KM (for example MYCOMPCLASS.km).

2. Load the newly created KM in the PATROL console.

3. Add the menu commands to this new computer class. These menucommands will eventually be merged with the menu commandsthat were already defined in the ALL COMPUTERS.km.

4. Save the KM.

5. Open the KM in a text editor and rename the COMPUTER CLASSfrom MYCOMPCLASS to ALL COMPUTERS.

6. Save the KM.

Another way is to remove everything from the ALL COMPUTERSKM but your own menu commands in the PATROL console (make sureyou have a copy of the original file somewhere). Save this new KM andrename the file to MYCOMPCLASS.km. The result will be the same.

9.5 Infoboxes

When ”infobox” is selected on the console, all infobox commands will besend to the agent and scheduled for immediate execution.

The Infobox has two types of entries: built-in entries at the top thatare hard-coded into the agent, and KM-specific entries at the bottom.Only KM specific entries can be added by the developer to extend thefunctionality of an infobox.

Page 184: Advanced KM Development

176 Menu Commands and Infoboxes

InfoboxInfobox commandscommands�� StdoutStdout �>� ¸� � ��� � µ�� ��>� ¸� � ��� � µ�� ��� � � · ���� � ¸� ���������� � ����� �¹·�¶ ! � � · ���� � ¸� ���������� � ����� �¹·�¶ ! �� -¸ ´�º#" �� � µ�� �ô%$ ¸ �-¸ ´º#" �� � µ�� �ô%$ ¸ �

Slide 9.4: Infobox commands

Typically infoboxes contain information about :

• Application Version

• Application’s installed directory name

• Knowledge Module version

• overall condition or status of the application.

The value shown in the right-hand portion of the infobox is set viathe PSL print() command.

Both PSL and OS commands can be used. Usually the OS macrocommand %ECHO is used because this results in very fast execution.(No rtcell, or PSL process is created if the agent sees the user just wantsto do a %ECHO command. An easy way to print a namespace variablesis :

%ECHO %{<variable>}

The output of a command defined in an infobox is sent to the textbox. If you execute an OS command you have to be careful your resultis in the first line, since only the first line will be visible.

Page 185: Advanced KM Development

9.6 Menu Commands and Infoboxes Pitfalls 177

9.6 Menu Commands and Infoboxes Pitfalls

9.6.1 Limit the script size

Since every menu command and infobox command will be sent over thenetwork to the agent, it is important to keep the scripts as small aspossible for two reasons :

1. Minimize network traffic

2. Minimize compile time on the agent

Because of this, you should consider moving all your menu commandcode to libraries. The only code that will be send over the network wouldthen typically be :

requires my menucmdlib;menu show preferences();

9.6.2 Delay in showing task output window

The task icon will only be created after the first line of output has beenreceived from the agent. If your menu command will show a report andhas to do some significant processing before the report is ready, it is agood practice to start the menu command with a print() statement sothe operator knows the agent has received your request.

If it takes a while before you even see that first line printed, then thiswill probably be caused by a combination of network delay and compi-lation time. Try putting you menu command in a library in that case.

Page 186: Advanced KM Development

178 Menu Commands and Infoboxes

Page 187: Advanced KM Development

Chapter 10

PSL Response Function

10.1 Response Function

The PSL response() function allows you to create interactive dialogboxes on the PATROL Console for information, collection, and presen-tation.

The function arguments of a response function defines the user in-terface elements.

10.1.1 Response Function Control

The first arguments of response() define the attributes of the responsefunction such as title, timeout and appearance. The following argu-ments define the layout of the generated response window. Each argu-ment contains a newline separated list of “type” with specific attributesof the type. Since each layout component is a separate argument in thecall to the response() function, it will be impossible to let your PSLcode build the desired response function. The only code variant part ofthe response() function will be the attributes of each type.

10.1.2 Response() Return Value

The response() function return value is again a newline separated list.The first line always indicates if the OK button (1) or the CANCEL but-ton (0) was pressed. Regardless of Accept or Cancel status, the returnlist fully describes the user’s choices.

This first line is followed by a list of result values for each of theelements that made up the response window.

179

Page 188: Advanced KM Development

180 PSL Response Function

The order of the return values is the same as the order that theelements were defined in the response() function.

The following elements do not return values:

• Labels (element types 0 and 1)

• Separators (element types 4 and 5)

• Frames (element type 14)

• Row and column compound elements (types 15 and 16)

• Icons (element type 17)

If a response( ) function time-out occurs, the function returns anempty string.

The PATROL Console can display multiple response() windows asit receives them from the Agent.

If multiple PATROL Consoles are connected to the same PATROLAgent, a response function window produced by a parameter recoveryaction will appear on each of them. In this situation, the first opera-tor that presses OK or CANCEL will in effect acknowledge them all.Clicking on the remaining response windows will cause any effect onthe agent, but they are not automatically removed.

Note: It is probably a bad idea to generate response windows from arecovery action. In case multiple agents have a problem, the op-erator could potentially receive a lot of response windows. Sincethere is no option on the console to close all response windows, thiswill be a manual task for the operator. In case you really want tocreate response windows from a recovery action, make sure to pro-vide a toggle so users can turn this option off.

If the response function window is generated in the context of a spe-cific console session, such as a menu command, only that console willsee the response window1.

1In case B=1 (broadcast property) is selected, all consoles that have the applicationloaded will see the response() function. This behaviour is not very useful.

Page 189: Advanced KM Development

10.2 Dynamic Response Functions 181

10.2 Dynamic Response Functions

In case you select the "D=1" property for the response() function, anasynchronous response function will be created. The return value of theresponse() function will now be an rid (response id).

You can continue to update the response window by specifying thisrid as the title of the response function.

The use of dynamic response windows is explained very good in thePSL reference manual.

10.3 Response Pitfalls

10.3.1 Ensuring only a single active response

This is a problem that a couple of developers have faced already.Let’s say you only want to allow one operator at a time to open a spe-

cific response box. That means you will have to use some sort of lockingto make sure that the second response function cannot be opened.

If you use locking (the real lock() function), you will see that theagent will automatically release all locks held by the PSL process themoment it dies, so it seems that the PSL lock function will be able tohelp us out on this.

A piece of PSL code to illustrate that :

if ( lock("MYLOCK","x",0)){

print("I’ve got the lock\n");}else{

print("Lock already held by someone else\n");exit;

}response("LOCK TEST","","","1\nCLICK TO RELEASE THE LOCK");

You will see this will work and will allow you to have only one re-sponse function of a specific type active.

But by doing this you have created another problem. Let’s say thatyour customer is using PATROL for 24h support and they have two op-erator sites (one in Belgium and one in Houston), so they can do ”followthe sun” support. A problem happened in Houston during daytime and

Page 190: Advanced KM Development

182 PSL Response Function

someone opened the response function.... Now what will happen if theguy who opened the response function forgot to close it ? 12 Hours laterthe same problem occurs. The guy in Belgium tries to open the responsefunction and gets a message that someone else already opened it ! Inorder to solve the problem (and get access to the response function), theguy in Belgium has to call the Houston office (probably no answer) orrestart the agent (drastic intervention, just to release the lock)So what do you probably also need here ? An emergency unlock feature!!I mentioned that a lock would automatically be released when a PSLprocess is killed, so we change the PSL script to the following :

if ( lock("MYLOCK","x",0)){

print("I’ve got the lock\n");set("lockpid",getpid());set("locktime",time());

}else{

lockpid=get("lockpid");locktime=get("locktime");

print("Lock already held by pid ".lockpid."timestamp=(".locktime.")\n");# Probably you would like to ask the user here if he# want to use the emergency# unlock ... we will presume he wants tokill(lockpid);print("We killed the process holding the lock, "."try again\n");

exit;}response("LOCK TEST","","","1\nCLICK TO RELEASE THE LOCK");

Indeed, it seems the process can’t be killed.... Well, this is somethingspecial, The process is in an IOWAIT state (see %PSLPS) and is there-fore not considered to be running. // So how can we fix that problem ?// Well, it is obvious that we won’t be able to kill the response function(because of IOWAIT state) if we write it like that. Maybe we can rewrite

Page 191: Advanced KM Development

10.3 Response Pitfalls 183

the response function so we can kill the PSL process ? // Take a look atthis code :

if ( lock("MYLOCK","x",0)){

print("I’ve got the lock\n");set("lockpid",getpid());set("locktime",time());

}else{

lockpid=get("lockpid");locktime=get("locktime");

print("Lock already held by pid ".lockpid."timestamp=(".locktime.")\n");# Probably you would like to ask the user here if he# wants to use the emergency# unlock ... we will presume he wants tokill(lockpid);print("We killed the process holding the lock, "."try again\n");exit;

}

#Open a dynamic response functionrid=response("LOCK TEST",

"","D=1","1\nCLICK TO RELEASE THE LOCK");

output="";while (!output){

output=response get value(rid,1);sleep(1);

}# Output received, kill itresponse(rid,"","K=1");

This will work, because we have created a while loop that will allowthe PSL process to come out of the IOWAIT state once every second...

Page 192: Advanced KM Development

184 PSL Response Function

this is enough to have the process killed (and release the lock in case ofemergency) !

There are other workarounds possible to this problem. What youcan also do is maintain a list (PIDLIST) with PID’s that started thismenu command (and will potentially modify something in the responsefunction) ... If someone saves the info, you check if his PID is (still) inthe PIDLIST.

If this is the case, you save the info and clear out the PIDLIST... Thiswill prevent anyone else from saving the info (because the PIDLIST iscleared).

If someone opens the response box after the info was save, his PIDwill be added to the list again and he will be able to save his info.

I don’t know if this procedure is clear, but it is not based on lockingand it is secure, because the list will only be cleared if someone saves theinfo (meaning that we don’t care about processes that die/disconnect)

10.3.2 Clicker behaviour

For some developers it just seems to be impossible to get the clicker el-ement in the response() function to work. Most of the times because ofthe inconsistency between the UNIX and the NT console, but sometimesalso because they didn’t clearly understand how it is supposed to workor behave. Before I get into the known problems, I would like to explainhow the clicker is supposed to work.

You know you have to specify a min value and a max value and adefault value. Let’s refer to them as min,max and default.

• Element syntax : R CLICKER,”MyClick”,min,max,default

• If default doesn’t lie between min and max, PATROL will take fordefault a value of (min+max)/2 !

• If min ¿ max then min=0 and max=100

On the UNIX console there is/was indeed a problem.The clicker window is sized according to the size of the default value.

The value will be correct (you just have to scroll in the small windowcontaining the number to see the actual value)

A possible workaround is to make sure the default value containsat least as much characters a there are character in min and max. (aleading zero will not work for default)

Page 193: Advanced KM Development

10.3 Response Pitfalls 185

min=−99;max=10;def=−50;

if ( def>max) { def=max; }if ( def<min) { def=min; }lenmin=length(int(min));lenmax=length(int(max));lendef=length(int(def));# Trap clicker problem...set default to something elseif (( lendef<lenmin) || (lendef < lenmax)){

def=(length(min) > length(max)) ? min : max;}

printf("min=%i - max=%i - def=%i\n",min,max,def);

Of course, this limits the use of this control a lot, because you willnot be able to set default really as you would like to. (but in cause youdon’t mind, this might be useful). An alternative might be to use theslider or another response() control.

Page 194: Advanced KM Development

186 PSL Response Function

Page 195: Advanced KM Development

Chapter 11

PSL Libraries

11.1 What PSL Libraries Are

PSL libraries are function libraries similar to other procedural lan-guages. They permit user-defined functions to be grouped into a logi-cal unit through combination into a physical library file. PSL librariesoffer the typical advantages of code reuse, extensibility by additionalabstractions, and space usage reduction.

PSL library files have a .lib suffix. The format of a .lib file is binary,and it contains compiled and optimized quad-code. The format is nota native executable or a DLL format. The binary format is platform-independent and does not suffer from portability issues, such as endian-ness or network byte order constraints. This platform independence isachieved through the use of a byte code format specific to PATROL.

If you use libraries to make the PSL command text in parameterssmaller, there is no real performance gain, because the PSL code forparameters is only compiled once. However, performance will increaseif you use libraries for menu commands.

Menu commands are compiled every time they are executed. Thiscompile time might be saved when you have complex menu commands.The menu command text would consist of as many library calls as pos-sible.

Libraries don’t contain a version at all. Actually none of the compiledPSL formats support versions. The agent will use the timestamp of thefile to see if the file was changed or not.

187

Page 196: Advanced KM Development

188 PSL Libraries

& ����� � -(')' ��* Ü\��Ü � �J� Û Ü9�& �J��� � -(')' ��* Ü\��Ü � �J� Û Ü9�

+-,o698<@~���WA7=?�����4769=�A/.10J�);9=?4769=�A32+C�0�,;9>z Q69D78 �,1)=)A7@)A71)=�;'1)> (4X �D}� ;9>$Dc6��547682+ Advantages99 F�G�MHA>K>;|KEG@Cc;;:�<�C=<?>c=F�G�MHA>K>;|KEG@Cc;;:�<�C=<?>c=

99 @c;>A�ItG@ABAV?�>cK>;|P�;>FC@�D%A};E>fMVK>G%AFA}?G>�CcF?H@c;>A�ItGBAIAV?�>cK>;|P�;>FC@�D%A};E>fMVK>G%AFA}?G>�CcF?H99 A};BAVG@AKJ-MHF�?@=@;A};BAVG@AKJ-MHF�?@=@;99 K>G@C�;|A>;�MHF�;K>GBCc;|A>;�MHF�;

Slide 11.1: What are PSL libraries ?

11.2 How the Agent loads libraries

The next slide shows how the agent loads libraries.

Page 197: Advanced KM Development

11.2 How the Agent loads libraries 189

L�! � �;�J� Û3ß��������!��J���¡� ��* Ü\��Ü � �J�L�! � �;�J� Û3ß��������!��J���¡� ��* Ü\��Ü � �J�

Kernel¯�M�¤�£¡�¡�

Memory Scheduler

NOPQRSTUUV

NOPQRSTUUW

NOPQRSTUUX

MemoryMemoryMemory

Y[Z�\�]C^=_C`CaIacbPatrolAgent

dfeIg hjiKkBlKmon?eIhjprq?sMemory

dEeKg hjiKkScheduler

tu vt wxyz{{|

tu vt wxyz{{}

tu vt wxyz{{~

Mem Mem Mem

dfhjiK�rpj� �=��eI�rn?p

requires libA;debug_level=4;myinit();....

if libA �%�E�%� �f�C�%�C�load libA;�o��� � libB �f�f�f� �E�?�%�o�

load libB;�o��� � libC �%�%�E� �f�C�f�C�load libC;

libA.lib

execute myinit� � � � �f�� � �f�?�C�C�c�C�C�?�E�� ���1��� � � �%�C�C�?�C� ��3�C�3� ����� �o� � �f�

Slide 11.2: How the Agent loads libraries

Page 198: Advanced KM Development

190 PSL Libraries

11.3 How to Use PSL Libraries

L�! � ��!¡ ��J� � -('¢' �£* ÜÃ� Ü � �J�L�! � ��!¡ ��J� � -('¢' �£* Ü\��Ü � �J�

¤7¥�1?������F�4cDX�,@)>¦¦ £¡�¨§�©�¥¼£¡��+£¡�¨§�©�¥¼£¡��+

mylibmylib;;ªª ?D DX;K«;¬cG@A>L�;>C�I�M®­cK>L ¯OG�­�F °?±@?@AK¯�?C²cD�;>F*I>A>G%³?D DX;K«;¬cG@A>L�;>C�I�M®­cK>L ¯OG�­�F °?±@?@AK¯�?C²cD�;>F*I>A>Gf³ ³F´@D ¯ ²³F´@D ¯ ² ?@A>;|?G±@?o¯ DO?%²cD�;?@A>;|?G±@?o¯ DO?%²cD�;¤7¥�1 ���oµ�D7;9Dc3

¦¦ �¡ �«�©�£¡¢[¶J(�¤­£¡¥§¤;·�/¼�¨¸º¹�©�£[�® �«�©�£¡¢M¨o©�¦�'¬¢�¥¼©�¦»¶�¡ �«�©�£¬¢�¶J(­¤�£¡¥§¤;·�/¼�¨¸º¹�©�£��¬ �«�©�£¡¢M¨o©�¦�'¬¢�¥¼©�¦»¶funcfunc>;>;ªª ;K«¼¬�G@A>L�;>C½±@?@AI¯O?%²cDO;|G@A�I�M�­cKEL ¯�G£­3?�±@?%¯ D�?o²cD�;;¯B­¿¾¿À�Á}L Âw?@L�A>;=ÃEM�¯�A>;>F;K«;¬cG@A>L�;>C½±@?@AI¯O?%²cDO;|GBA�I�M�­cKEL ¯�G£­3?�±@?%¯ D�?o²cD�;;¯B­¿¾¿À�Á}L Âw?@L�A>;=ÃEM�¯�A>;>F

librarylibrary

Slide 11.3: How to Use PSL Libraries

11.3.1 Requires

A PSL script loads a PSL library using the requires keyword. The re-quires keyword is followed by the library file name, either directly as anidentifier or in double quotation marks as a string literal. Assuming theexistence of a PSL library file named myfuncs.lib, the following requiresstatements should be identical:

requires myfuncs;OR

requires "myfuncs";OR

requires "myfuncs.lib";

The use of a file extention outside the quotation marks is not al-lowed, as shown in the following statement:

requires myfuncs.lib; # ERROR!

When the PSL compiler encounters a requires statement, the agent

Page 199: Advanced KM Development

11.3 How to Use PSL Libraries 191

loads a PSL library file into memory if it has not already been loaded (forexample, if it was required by another PSL script). The agent must findthe library file in the ”/lib/psl” directory offset from the PATROL HOMEenvironment variable. The functions and global variables that havebeen exported by the PSL library can be used in the PSL script at anypoint after the requires statement.

This process is similar to performing a syntax check of a PSL scriptcontaining a requires statement from a PATROL Developer Console.However, the console will also look in the local directory area before theglobal area for the PSL library file when loading it.

A function can be exported before the definition. A function cannothave the same name as a built-in PSL function name such as ntharg()or grep().

11.3.2 Export

The main keyword in the definition of a PSL library is export. This key-word is used to explicitly export a PSL user-defined function or a PSLglobal variable. A function can be exported by the export function syn-tax, as shown below:

export function myfunc;

Page 200: Advanced KM Development

192 PSL Libraries

11.4 Exporting Variables

A global variable in a PSL library can be exported using the ”export”syntax:

export myvar;A global variable can be exported before its first use. A function’s localvariable cannot be exported. Exported global variables have a distinctvalue for each PSL process using the PSL library. Therefore, they arenot exactly like variables inside a DLL, where there would be only onevalue for any global variable. For example, if two PSL scripts require alibrary, and it exports a global variable ’x’, then the two PSL scripts canset ’x’ to different values without interfering with each other.

This is usually convenient in preventing bugs, but can be limiting inthat there is no way for PSL processes to use PSL libraries to communi-cate with each other. On the other hand, the PSL get()/set() namespacefunctions is more than adequate for PSL processes to communicate to-gether, so this is not a major disadvantage.

Exported global variables cannot be automatically initialized. Theyhave the empty string at startup of the PSL process, just like all PSLvariables, but reliance on this fact can trigger a PSL runtime warningmessage if you have the ”PslDebug” settings enabled.

There is no way for a PSL library to automatically call an initializa-tion function when it is loaded. Instead, the only solution is an explicitinitialization function in the library that must be called by every PSLscript that uses the library. Alternatively, this can be hidden by call-ing the initialization routine before any other library processing occurs,but this is less efficient since it requires checking each time whetherinitialization has occurred yet.

Page 201: Advanced KM Development

11.5 Exporting Functions 193

Ä�¤�¦"! Ü\� � ��ߢÅ�� Ü � � * �����Ä�¤�¦"! Ü\� � ��ߢÅ�� Ü � � * �����

Æ0AX�9@�69D7> myvar;ÇÇ ±7©=«�©�+z+�¥K·�¥�/§¥§¢oÈ=¢�©=¤�+z+�¥ÊÉ­¦�¥¼¦�¥§¢�¥¼¤�/N(�¤�/K©��ÌËC˱7©=«�©�+f+�¥K·�¥�/§¥§¢oÈ=¢�©=¤�+z+�¥ÊÉ­¦�¥¼¦�¥§¢�¥§¤�/N(�¤�/K©��ÌËCËÇÇ ��/�,Τ;È�+�¥§¦�¥¼¢�¥¼¤�/§¥KÍ¡�¡�g¢�©ÏÎ;Ð��/�,Τ;È�+�¥¼¦�¥§¢�¥¼¤�/¼¥ÊÍ¡�¡�g¢�©ÏÎ;ÐÇÇ ±7©�¢[Î�¯�M�¤�£¡�¡��ÐÏ·��¡¢,7�¬�¡¦»Ñ�¯�ÒÝ«�£¡©�'¡��+z+���+±7©�¢[Î�¯�M�¤�£¡�¡��ÐÏ·��¡¢,7�¬�¡¦»Ñ�¯�ÒÝ«�£¡©�'¡��+z+���+Ó ¦�©­¢|/§¥�.��?¤V'Ó ¦�©�¢|/§¥�.��B¤V'

--static)static)

Æ ��¡)A71çBÍ¡�3¢�)F`Ap�,>ÕÔÇÇ ±7©ÖÑ�¯�Ò#'¡©­ªg«�¥�/§��,Τ�£¡¦�¥¼¦®É�µjÐÖ×7¤�£¡¥¼¤;·�/¼�F©�+k�¡�»·�©�¢M¦�©�¢|+k�¡¢Cб7©ÖÑ�¯�Ò#'¡©­ª�«�¥�/¼��,Τ�£¡¦�¥¼¦®É�µjÐÏ׳¤�£¬¥§¤;·�/¼�F©�+k�¡�»·�©�¢M¦�©�¢|+k�¡¢CÐ

Slide 11.4: Exporting Variables

11.5 Exporting Functions

11.5.1 Code Sharing

The main purpose of libraries is to allow code sharing. However, codesharing doesn’t mean that all the functions defined in the library areautomatically exported and usable by the process that needs it.

11.5.2 Code Reuse

To make a function available to a process that requires the library, itmust be exported in the library first. This means that all non-exportedfunctions in the library are callable only in the library. Every libraryfunction is stored only once inside the agent’s PSL cache and all PSLprocesses will use the same function code from the cache.

11.5.3 Function Variables

The data will be private to the PSL process (there is no call by refer-ence possibility with PATROL) and will be duplicated for the library.

Page 202: Advanced KM Development

194 PSL Libraries

This means that the library function can’t change the data for any ar-guments.

11.5.4 Function Hiding

Call by reference is simply impossible because every library functionduplicates the arguments before using it. However, the library can ac-cess variables that belong to the PSL process. Therefore, the functioncode is executed in context of the PSL process that called it.

Ä�¤�¦"! Ü\�\�J�£�;���J��� � !��J�Ä�¤�¦"! Ü\�9���£�;���J��� � !��J�

Ø7Ù ¡)3¢�)F`Ap�,>ÏÔÚÚ ²½M��B¨%©�¦�'¡¢�¥¼©�¦�'¡©����?¥�+S+1M�¤�£¬�¡��¥¼¦»Ñ��7²½ÛÝÜÌÞݪ��¬ª�©�£¨ß;ಽM��B¨%©�¦�'¡¢�¥¼©�¦�'¡©����?¥�+S+1M�¤�£¬�¡��¥¼¦»á��7²½ÛÝÜÌÞ[ªg�¬ª�©�£¨ß;àÚÚ ²½M���'¬©�����'¬¤�¦»·��?£¡�¨©�+k�¡�g¥§¦�á�¯®Þ#'¡¤�'¨M��âಽM���'¬©�����'¡¤�¦»·��?£¡�â©�+��¡�g¥§¦�á�¯�Þ '¡¤�'¨M��âàÚÚ ãä©�¦�'¡¢�¥¼©�¦�(�¤�£¡¥§¤�å�/§��+�¤�£¡��/¼©�'¡¤�/u¨�©­£B¢oM���áJ¯�ÞÝ«�£¡©�'¡�*+z+1àãä©�¦�'¡¢�¥¼©�¦�(�¤�£¡¥§¤�å�/§��+�¤�£¡��/¼©�'¡¤�/u¨}©�£B¢oM���á�¯�Þ «�£¡©�'¡�*+z+1àÚÚ æT �«�©�£¡¢��¬��¨%©�¦�'¡¢�¥¼©�¦�+S'¡¤�¦p'¡¤�/�/u¦�©�¦æT �«�©�£¡¢��¡��¨%©�¦�'¡¢�¥¼©�¦�+S'¡¤�¦p'¡¤�/�/u¦�©­¦

--�¡ �«�©�£¡¢��¡�g¨o©�¦�'¡¢�¥ ©�¦�+�à�¡ �«�©�£¬¢��¡�g¨o©�¦�'¡¢�¥ ©�¦�+�à

Slide 11.5: Exporting functions

Page 203: Advanced KM Development

11.6 Creating PSL Libraries 195

11.6 Creating PSL Libraries

The PSL stand-alone compiler executable is called psl. This commandis used to create PSL libraries and binaries. The syntax to create a PSLlibrary .lib file is the -l option, like this : psl -l myfuncs.psl

This command creates the myfuncs.lib file in the current directory.This command must be executed in the current directory containing my-funcs.psl. Additionally, the command does not automatically find PSLfiles in either local or global directories.

You cannot create or edit PSL libraries from the developer console.The only method is from the command line using the psl executable.

  Ü\�J��� � ��ß � -(' � ��* Ü\� Ü � �J�  Ü\�J��� � ��ß � -(' � ��* Ü\� Ü � �J�

çEèâéoê¼ë ì£íIî�ïCðEìBñ êcï myfunc;

íIî�ïCðEìBñ ê¼ï myfuncò ó ë ô¼õ=ö ó ë ô£÷=ø£ùprint(“ func (“ .arg1.” ,” .arg2.” )\n” );

}

mylib.psl

ú�û%ü?ý þú ÿ��mylib.lib

psl -l mylib.psl(commandline)

Slide 11.6: Creating PSL libraries

Page 204: Advanced KM Development

196 PSL Libraries

11.7 Nested PSL Libraries

There is no limit to the level of nesting allowed in PSL libraries. A PSLscript can require library A which requires library B which requires li-brary C, and so on. In this case, B must exist before A will compile, andC must exist before B will compile successfully. Therefore it is clear thatthe compilation sequence has to start at the bottom or leaf nodes of therequires hierarchy. The sequence of A requiring B requiring C wouldbe:

psl −l C.psl # creates C.libpsl −l B.psl # creates B.libpsl −l A.psl # creates A.lib

There is no implicit inheritance of the exported functions. For exam-ple, if A requires B which requires C, then A cannot call the functionsexported by library C unless A explicitly requires also library C.

���J���\�J� � -�' � �£* Ü\� Ü � ������J���\�J� � -(' � �£* Ü\� Ü � ���

ç=èâéCê¼ë ì£íBî£ïCð=ìIñ êcï��£ç��£îCô��íBî£ïCð=ìIñ ê¼ï��£ç�£î?ô ò ó ë ô¼õ=ö ó ë ô£÷=ø£ùé£ëjñ ïCì ò ô�çEì ò� ï ó � ç��jø�� ����������ò� � ó ë ô¼õ�� �rø������ ó ë ô£÷�� � \n” );}

libC.psl

requires libC;ç=èâéCê¼ë ì£íBî£ïCð=ìIñ êcïäñ ïCí ê��íBî£ïCð=ìIñ ê¼ïäñ ïCí ê ò ó ë ô;õKø£ùñ í ò �£ç�£î?ô��� ç� Eç�� !#"=ø£ùdebug(“ INFO” ,arg1);

}}

libB.psl

requires libB;ç=èâéCê¼ë ì£íBî£ïCð=ìIñ êcï myinit;íBî£ïCð=ìIñ ê¼ï myinitò ø£ùñ ïCí ê ò�%$ î£ï?ðEìBñ ê¼ï¿ñ ï£ñ ì�ð ó � � ç&���rø��}

libA.psl

psl -l libC.psl

psl -l libB.psl

psl -l libA.psl

ú ûfü ý þú ÿ �

libC.libç=èâéCê¼ë ì ç&�äíIî�ïCðEìBñ ê¼ï%'!(�£ç��£îCô ò ø

) ú�û ü ý * þú ÿ �

libB.libçEè�éCê¼ë ì ç��äíIî�ïCðEìBñ ê;ï%'!�ñ ïoí ê ò ø

) ú�û%ü?ý * þú ÿ �

libA.libçEèâéoê¼ë ì ç&�äíBî£ïCð=ìIñ ê¼ï+'> myinit()

Slide 11.7: Nested PSL libraries

Page 205: Advanced KM Development

11.8 Statically Linked PSL Libraries 197

11.7.1 Cyclical Dependencies of PSL Libraries

Cyclical dependencies of PSL libraries are also not handled well. Al-though there is no explicit prevention of cyclical requires situations,they do create problems. For starters, how do you compile them? If Arequires B and B requires A, then A must exist to create B, and B mustexist to create A. It is like the chicken and egg. You can get around thisthrough some tricks involving bootstrapping the library by compilingthe first one without the cyclical dependency and then recompiling bothlibraries. However, since it can cause unpredictable agent behavior, whywould you want to do this?

11.7.2 Three or More Levels of Libraries

More than three levels of nested libraries can cause unpredictable agentbehavior. This refers to the situation in which A requires B, B requiresC, C requires D, or any deeper nesting. This problem is fixed in PA-TROL 3.1 agents but may affect compatibility of the KM to PATROL3.0 agents. Fortunately, three levels of nesting are usually adequate formost KM needs.

11.8 Statically Linked PSL Libraries

PSL libraries can be statically linked via the psl -s option. This capa-bility is is not really useful and is still there for historical reasons. Youshould not use this because it can cause unexpected results. Also staticlibrary merging loses the advantages of nested libraries where lower-level libraries would only be used once.

11.9 Performance Issues of PSL Libraries

There is no difference in run-time performance in terms of CPU us-age whether a user-defined PSL function is stored in a PSL library ordirectly in a main PSL file. The advantages of PSL libraries arise incoding practices rather than performance.

There is also no performance penalty when you use PSL libraries.All libraries are internally cached by the agent and have the same per-formance as other PSL scripts.

Page 206: Advanced KM Development

198 PSL Libraries

The agent does gain some memory usage when you use PSL libraries.The agent maintains only one copy of the read-only data for a PSL li-brary, including all the quad-code instructions, constants, and linkagedata. The process of using a PSL function in a library rather than copy-ing it into many files, which is poor programming style, saves the agentsome memory. The agent maintains multiple copies of PSL library dy-namic information, such as the values of local, global and exported li-brary variables, with one copy per PSL process using the library.

11.10 Debugging PSL Libraries

The PSL Debugger does not provide adequate support of PSL libraries.There is no support for multiple PSL source file viewing in the debugger.Therefore, although you can step through a PSL library, you will bestepping blindly without viewing the source code as you step. Thereare also problems with using print() and break() and other statementsbecause the debugger does not fully handle library context and mayconfuse the context of local or global variables in the PSL library withthose in the main script.

11.10.1 Solution to Debugging PSL Libraries

The solution to debugging PSL libraries is to use debugging printoutstatements with PSL print() or PSL printf(). This is a simple andeffective solution. The debugging flags need to be externally controlledby the client using the PSL library. One solution is to export a globalvariable, called myfuncs Debug, and have the client PSL script set thisvariable if debugging is desired. Another alternative is a PSL exportedlibrary function to control debugging settings.

11.10.2 Changing PSL Libraries

There are a number of difficulties when changing PSL libraries duringKM development. Understanding the following issues will help avoidproblems and save time.

11.10.3 Loading New PSL Libraries

The PATROL agent does not automatically load a new PSL library.libfile. Instead, it retains the older version of the library in memory, even

Page 207: Advanced KM Development

11.11 Problems with Nesting 199

after all PSL processes that required it have terminated. Therefore,when updating a new .lib file, you cannot simply unload a KM or kill allPSL processes. Unfortunately, the only method is to kill and restart theagent or to use the Reinitialize Agent menu command.

11.10.4 Commit Does Not Work for Libraries

Getting the PSL library .lib files to the agent is another issue. PSL li-braries are not automatically downloaded by the developer console, norare they picked up by the Commit KM menu command. Thus, PSL li-brary files have to be manually copied to the agent machine via FTP orNFS sharing or network drive mapping. Another possibility, developingthe PSL library directly on the agent machine and executing psl -l di-rectly in the agent’s global directory, can be effective, but is confusing ifsome files are created on the console and others on the agent.

Developing the PSL library on the agent machine does not work wellwhen developing or testing on more than one agent.

11.11 Problems with Nesting

Nested libraries also impose an annoying sequence when you change alibrary. When you change a low-level PSL library, you must recompileall PSL libraries (or PSL binaries) that require that library. If library Arequires B, then changing B will also require recompilation of A. How-ever, changing A does not require a recompilation of B. Often, when youchange a low-level library, you will have to recompile many libraries andcopy all these new library files to the agent’s global directory. An auto-mated script or makefile is recommended to automate this compilationsequence of libraries.

A trick to changing libraries without having to restart the agent is tochange the name of the library and recompile it. Don’t forget to changeyour requires statement in the KM.

11.12 How to Change PSL Libraries

A number of steps are involved when changing a PSL library. Thischange places an elongated cycle when developing a KM involving PSLlibraries.

Page 208: Advanced KM Development

200 PSL Libraries

These steps are necessary because of a design flaw involving latelinkage of the PSL library and binary format. Function and variablenames are mapped to integer offsets too early. This mapping makesPSL library loading efficient because it does not need to happen in theagent, but it leads to these problems of inflexibility when the functionschanged.

The agent can experience strange failures if some of these steps aremissed. The agent has difficulties handling inconsistent PSL libraries.Fortunately, it does not crash; it will offer a number of error messagessuch as ”fatal inconsistency detected.“

Not all failures are this obvious. Some of the ”quiet” failings involvethe wrong PSL library function called or the wrong global variable ac-cessed. When debugging a KM or PSL error that appears to defy logic,consider the possible failings from PSL libraries.

Did you restart the agent the last time you changed some libraries?Did you recompile dependent PSL libraries when you changed just

one of them?Did you copy the newly created ”.lib” library files down to the agent’s

global ’psl’ directory before restarting the agent?In the face of strange behavior or a PSL coding bug you thought you

had fixed, these PSL library issues could be causing you to chase ghostsinstead of your real PSL coding bugs.

Page 209: Advanced KM Development

11.12 How to Change PSL Libraries 201

  ���L��ß � ��ß � - ' � ��* Ü\��Ü � ���  ���L�Fß � ��ß � -(' � ��* Ü\��Ü � ���

, ¥`FVFc�)A.-�F0/11 2T©�¤���¥¼¦43Φ���,Î�¡£�(��¡£*+�¥§©�¦�+2T©�¤���¥¼¦43Φ���,Î�¡£�(��¡£*+�¥§©­¦�+

55 U =@;�6cL�CcG@;EF768�L�A>;�6c;&9�D : ;HA>?@A�:O;>F�:�6.<V;�<VG@A�=U =@;�6cL�CcG@;EF768�L�A>;�6c;&9�D : ;HA>?BA>:O;>F�:�6.<V;�<VG@A�=55 F�G�D MHL :�G?6A@�A>;>K�=�K�D�;J?@=@;�6cLF�GD MwL :�G?6A@�A>;>K�=�K�D�;J?@=@;�6cL11 BÝM�¤�¦43��¡��/§¥>C�£¡¤�£ DI���¡¢��*'¡¢�¥¼©�¦�©­¦FEHGJI\4BÝM�¤�¦43��¡��/§¥>C�£¡¤�£ DI���¡¢���'¡¢�¥¼©�¦g©�¦FEHGJI_411 B7©­ª�ª�¥§¢M��©��*+�¦LK ¢|,Ω�£�.g¨�©�£�/¼¥MC�£¡¤�£¬¥§��+B7©­ª�ª�¥§¢M��©��*+�¦LK ¢|,Ω�£�.g¨�©�£�/¼¥MC�£¡¤�£¬¥§��+

55 ExtraFilesListExtraFilesList parameterparameter11 N�£¡©JC�/¼�¬ª�+S,Î¥¼¢CM�¦��*+�¢�¥¼¦43N�£¡©JC�/¼�¬ª5+-,Î¥¼¢CMg¦���+�¢�¥¼¦4355 A>;EK>G�<PO�: DO;|C�;�Oc;&6�Cc;�6cK�:O;>F:�63KEG@AEA>;>KEL�G@AECc;>A(QMQA>;EK>G�<PO�: DO;|C�;�Oc;&6�Cc;�6cK�:O;EF�:�63KEGBA>A>;EK>L�G@AECc;>A(QMQ

Slide 11.8: Changing PSL libraries I

L�! � ��!   ���L��ßL� � -('¢' �£* Ü\��Ü � �J�L�! � ��!   �J�L��ßL� � -('¢' ��* Ü\��Ü � ���

R?��>�A7@)FSS TÝM�¤�¦43��?¢CM��VU�¯42 /¼¥MW�£¡¤�£�X=¢��¡ �¢M¨�¥�/§��YTÝM�¤�¦43��?¢CM��VU�¯42 /¼¥MW�£¡¤�£�X=¢��¡ �¢M¨�¥�/§��YSS Z7��'¡©­ª�«�¥�/¼�?¢CM��[U�¯42 /§¥>W�£<¤�£ XV(�¥¼¤Z7��'¡©­ª�«�¥�/¼�?¢CM��[U�¯42 /¼¥MW�£<¤�£�X�(�¥¼¤

pslpsl --/u¢�©�'¡£¬�¡¤�¢��?¤�¦���,\Y_/§¥MW/u¢�©�'¬£¡�¡¤�¢��?¤�¦���,\Y_/§¥MW

file.file.SS Z7��'¡©­ª�«�¥�/¼�?¤�¦4X=���¡«��¬¦����¡¦�¢M©�¢CM��¬£VU�¯42#/§¥>W�£¡¤�£ XI¨�¥�/ ��+S,Î¥§¢oMZ7��'¡©­ª�«�¥�/¼�?¤�¦4X=���¬«��¡¦����¡¦�¢M©�¢CM��¬£VU�¯42#/§¥>W�£¡¤�£ XI¨�¥�/ ��+S,Î¥§¢oMpslpsl --l.l.SS T7©�«4X=©­£^]�²^UY©�¦��B©�£Dª�©­£¡��'¨M�¤�¦43��¡�_Y_/§¥MWg¨�¥�/§�*+�¢�©I¢CM��T7©�«4XI©�£^]�²^UY©�¦��B©­£?ª�©­£¡��'¨M�¤�¦43��¡�_Y_/§¥>W�¨�¥�/¼��+�¢�©I¢CM��¤J3��¡¦�¢?` +L3�/¼©JW�¤�/¤J3��¬¦�¢�` +L3�/¼©JW�¤�/

pslpsl directory.directory.SS aT¦�+1©�£¡�?¢oM�¤­¢|/§¥>W�£¡¤�£ XI¨�¥�/§�B«��¡£¬ª�¥�+z+�¥§©­¦�+ ¤�£¬�B¤­���¨§�©�¤�¢��?¢�©aT¦�+1©�£¡�?¢oM�¤�¢|/§¥>W�£¡¤�£ XI¨�¥�/§�B«��¡£¬ª�¥�+z+�¥§©­¦�+ ¤­£¡�?¤����¨§�©�¤�¢��?¢�©¤�/�/§©�,õ¢oM��?���<¨�¤;©�/¼¢M¤J3��¡¦�¢ ¤�'�'¬©;©�¦�¢M¢�©I£¡�¡¤��g¢CM���/¼¥MW�£¡¤�£�X=¨}¥�/¼��+#Y¤�/�/§©�,�¢CM��?���<¨�¤;©�/¼¢M¤J3��¡¦�¢ ¤�'*'¡©;©�¦�¢M¢�©I£¡�¡¤��g¢CM���/¼¥MW�£¡¤�£�X=¨}¥�/¼��+#Y

SS Z7��+�¢�¤�£¬¢M¢CM��?¤J3��¡¦�¢+YZ7��+�¢�¤�£¬¢M¢CM��?¤J3��¬¦�¢%Y

Slide 11.9: Changing PSL Libraries II

Page 210: Advanced KM Development

202 PSL Libraries

L�! � ��!   ���L��ßL� � -('¢' �£* Ü\��Ü � �J�L�! � ��!   ���L��ßL� � -('¢' �£* Ü\��Ü � �J�

(continued)(continued)

b7¥�8<@)D76dc9A78<A71)>$FV�,1 40eAf g

hh ikjHlnmpoq2Arf7As7�tsnr�u�¯ikjHlHmvoq2Arf7As7�tsnr�u�¯

hh �H3��¡¦�¢|'¨M���'�.�+S/¼¥Mw�£¡¤­£ x=��¥¼¨�¨}�¡£¡�¡¦�'¬�^y���¥�+z.{z�H3��¡¦�¢|'¨M���'*.�+-/¼¥Mw�£¬¤�£ xI��¥§¨�¨}�¡£¡�¡¦�'¬�^y���¥�+z.4zmemmem | ¤­¢do�¯42| ¤­¢do�¯42

'¡©­ª�«�¥�/¼�B¢�¥§ª��~}'¡©­ª�«�¥�/¼�B¢�¥§ª��~}

Slide 11.10: Changing PSL Libraries III

11.12.1 %DUMP LIBRARIES

In PATROL 3.1 there is no way to detect the status of the libraries.However, PATROL 3.2 offers the built-in agent command %DUMP LI-BRARIES to list the PSL libraries and when they were loaded.

11.12.2 Library Difference Checking

The 3.3 agent also has a warning on PSL script compilation if the agenthas a library in memory, but the file on disk appears to be more recent.This helps to identify situations when the agent has not been bouncedsince a PSL library was changed. However, this does not help in theinconsistency problems involving nested library dependency problems.

11.13 Determining Library Dependencies

The PSL standalone compiler, ”psl”, has a feature to report on whichPSL libraries are required by another PSL script or binary file. The ”-R” option is used to report on the dependencies for a file. Some examples

Page 211: Advanced KM Development

11.13 Determining Library Dependencies 203

would be:psl −R myfuncs.psl # check PSL sourcepsl −R myfuncs.bin # check PSL binary

The output from the ”-R” option is either a report that no PSL li-braries are required such as: ’myfuncs.psl’ requires no PSL libraries.

Alternatively, if PSL libraries are required, the output will look sim-ilar to:

’myfuncs.psl’ requires the following PSL libraries:libA DYNAMIC PSLlibB DYNAMIC PSL

The status (second argument) is either dynamic or static dependingon whether the ”-s” option to ”psl” was used to create a static linkedlibrary. Generally, all PSL libraries are dynamic.

���0�J��Üd���?�k�?��ß � -('�� � * ÜJ��Ü�$����������q�����q����������0�J� Üd���?�k�?��ß � -('�� � * ÜJ��Ü�$������q���q�����0�������

� psl -� f>f�f>f�� ,Ω�£�.�+�¨�©�£V�J�,Ω�£�.�+�¨�©�£V�J�

pslpsl ¤�¦��_�J��w�¥§¦g¨�¥�/¼�¤�¦��_�J��w�¥ ¦g¨�¥�/¼�

�0BC6'D7E�;9D76��)1)=  $69D��df ���%��� cpcp mylibmylib.lib.lib mylibmylib.bin.bin�� pslpsl --RR mylibmylib.bin.bin

'mylib'mylib � ���  J¡M¢¤£�¥+¦�� ¢¤£&§©¨ ª�£(«M¬?­ ­ ¬�®��� �¯©°{±#²³­ � ��¢¤´>¢>�7£&§7µ� ���  J¡M¢¤£�¥+¦�� ¢¤£�§�¨ ª�£(«M¬?­ ­ ¬ ®J�� �¯©°{±�²~­ � ��¢¤´>¢>�7£&§7µ­ � �?¶­ � ��¶ ·A¸�¹ ¶.º¼»¤½^°{±#²·^¸�¹ ¶.º¼»¤½^°{±#²­ � �?¾­ � ��¾ ·^¸�¹ ¶dº¼»¤½^°{±#²·^¸�¹ ¶dº¼»¤½^°{±#²

Slide 11.11: Determining PSL library Dependencies

Page 212: Advanced KM Development

204 PSL Libraries

11.14 Library Type

The type refers to whether the library is a normal PSL library, as dis-cussed here, or an XPC-based DLL-like PSL library, which is discussedelsewhere.

Unfortunately, the ”-R” function is not supported on PSL libraryfiles, and fails with an error message:

psl −R myfuncs.lib # check PSL library NOT SUPPORTED!

This is a limitation of the psl executable and not a problem with thelibrary file formats. One inelegant workaround for that may well be tocopy myfuncs.lib to myfuncs.bin, and then try cmdpsl -R myfuncs.bin.Because of the similarity of ”.bin” and ”.lib” file formats, this will showthe library usage dependencies.

11.15 PSL Binaries

It is also possible to compile the PSL scripts you saved in a seperatePSL file to PSL binaries. With the command psl -b myscript.psl, youwill generate a myscript.bin file.

When distributing the KM you can decide not to distribute the sourcePSL files, but the .bin files instead.

The PSL binaries also don’t have a version number. Binary files willbe unconditionally committed.

11.16 Pitfalls

11.17 Limitations of PSL Libraries

Unfortunately, PSL libraries suffer from a long list of limitations thatdetract from their value. Nevertheless, almost all large KM projectsnecessarily involve PSL library files. Some of the problems that remainto be overcome are as follows:

• The Developer Console KM downloading does not send PSL libraryfiles.

• Commiting a KM does not send PSL library files.

• The -R option does not work on .lib files.

Page 213: Advanced KM Development

11.17 Limitations of PSL Libraries 205

• The -R option requires the libraries to exist and reports an error ifit does not exist.

• The psl function only finds libraries in the current directory andhas no -I or -L option to give an alternative directory. However, anenvironment variable named PSL LOAD PATH can be used.

• There is no way to create libraries from the Developer Console KMediting dialog boxes.

• The PSL Debugger does not handle PSL libraries well.

Despite these problems, the use of PSL libraries is good coding prac-tice. It encourages code modularity and reuse and simplifies larger PSLcoding problems. The problems with distribution are usually solved byincluding the PSL library files in agent-side installation routines. Themajority of other difficulties occur during development of the KM anddo not affect the end user of the KM.

' �?�����J���(��!��0� !�¿���À '�� � * ÜJ��Ü(�+�0�' �?�����J���(��!��0� !k¿¿��À '�� � * ÜJ��Ü(�+�0�

Á�Â0ÃÅÄ�Ã(Æ\Æ£�%Ç^È+ÉLÃ(Ê�Ë~�7Ã(ÌdÉ#.7ÍX�(Ä�Í�ÎÏÇ ExtraFilesList)Á�Ð0Í�ÎÏÍ�ËÏÉÏÍ�ËÏÄ��%Í�Ñ . psl -� Ê�ÃdÒ�ÓÔÌdÒ�Ã��LËÏɺ2Á�Â0ÃÅÕnÖ#� �k×�ØÚÙ0Û ¥PÑ*�ÏÎÏÎLÃdÒ�ÇÁ�Ð"�� z f�%ÄN�-�+Ç^ÉLÍ�Ü~�S¦�¦|�%Ë~¦Á�Â0â���%ÜÏÒ�ÌdÒ�Ý��LË~�%ÃdÌdÉ

Slide 11.12: Limitations of PSL libraries

Page 214: Advanced KM Development

206 PSL Libraries

11.17.1 Libraries Must Be Present at Compile Time

The PSL engine will try to compile any piece of PSL code before runningit. When compiling, it determines whether the libraries exist. If noneof the library functions are called, the agent will issue an error; and thescript compilation will fail if the library does not exist.

11.17.2 The Console Doesn’t Distribute Libraries

Some developers forget that their application is not installed on everymachine. This can be very annoying if you put require statements inprediscovery. If the application does not exist on the system, it is verylikely that no one installed the KM on that system and therefore thelibrary will not be present.

11.17.3 Prediscovery Will Fail

If the PATROL administrator didn’t put the KM in the “DisabledKMs”setup variable, an error message will be displayed in the console window(couldn’t load library....).

Do not put the requires statement as one of the first lines in the pre-discovery without first determining whether the application is installedon the system.

If the library is installed on the system and the agent loads it, it willbe loaded in agent memory and can’t be unloaded. If your applicationdoesn’t exist on the system, you might want to set active to zero (unloadthe application).

Page 215: Advanced KM Development

11.17 Limitations of PSL Libraries 207

Þ !ß��� !�� ���+�J¿J� �?� �Þ !ß��� !�� ���+�J¿�� �?� �

à�á0â¢���%ÜÏã�ädã��+å�æ��+ç prediscoveryèè /¼¥Mé�£¡¤�£¬¥§��+�ª ©�+�¢(é��?«�£¡��+��®¦�¢ ¤­¢|'¡©­ªg«�¥�/§�?¢�¥§ª��/¼¥Mé�£¡¤�£¬¥§��+�ª ©�+�¢(é��?«�£¡��+��®¦�¢M¤�¢|'¡©­ªg«�¥�/§�?¢�¥§ª��èè '¡©�¦�+k©�/§�?��©���+k¦Lê ¢M��¥�+k¢�£¡¥>é�©�¢���/¼¥Mé�£¡¤�£¬¥§��+'¡©�¦�+k©�/§�?��©���+k¦Lê ¢M��¥�+�¢�£¡¥>é�©�¢���/¼¥Mé�£¡¤�£¬¥§��+èè prediscoveryprediscovery ,7¥�/�/�ë��Hì#2ßí,7¥�/�/©ëJ�Hì#2ßí

îî exampleexampleïï ð ñ�ò�ó�ô�ô�õ ð ö?ó�÷ ð ø#ù&ú�û+ü&ð�ý ÷�ý þnÿð ñ�ò�ó�ô�ô�õ ð ö?ó�÷ ð ø�ù&ú#û%ü&ð�ý ÷�ý þnÿrequiresrequires mylibmylib;;....FAILS....FAILSà ,På�ã��f� E����ä��E�%âdç /��0���%åFçLä����%ç~¦���âdçLcdå�ç��E�%âdçLæ"�E�

Slide 11.13: Library Pitfalls

Page 216: Advanced KM Development

208 PSL Libraries

Page 217: Advanced KM Development

Chapter 12

Configuration Variables

The PATROL agent allows for persistent storage of configuration vari-ables. This storage is often referred to as the pconfig database. We willfirst see how the agent initializes this database and then explain someof the special configuration variables.

12.1 PATROL Agent Initialization Process

As the PATROL Agent initialization process begins, the agent first checksif the ASCII $PATROL HOME/lib/config.default file has changed sincethe last time the agent was started. If this file was not changed and thebinary configuration file exists in the $PATROL HOME/config directory,the binary configuration file is read and the agent proceeds with the restof the startup procedure.

If the binary configuration file does not exist, or config.default waschanged, the PATROL Agent process reads the ASCII config.default fileand creates/loads it into the binary configuration file.

12.2 Text Configfile Format

When you edit the configuration change file, you should observe thefollowing guidelines:

• The PATROL CONFIG command must appear at the top of thefile.

• A comma must end every entry except the last one.

209

Page 218: Advanced KM Development

210 Configuration Variables

• The change entries can appear in any order and are applied in theorder of appearance.

• White space is ignored except within double quotation marks.

• Comment lines begin with an exclamation point (!).

When defining changes or adding new variable to this file, you shouldbe aware of some contraints :

Variable path You can use any path to define the variable in a config-uration file. The pathlength is limited to 1024 characters.

predefined variables Depending on certain endings of a variable name,the agent will give the variables a special meaning. An example is: defaultAccount.

FormatFormat

Ignored � ���������������������������� ������������� �"!�� ����#$����� %&�('*),+���������-��� �.!�� ����#(�/���0%1�$'�)2+

4365 798;:�<=5 >@?BADC6EGFIHGJLK6MONPJLQG36R;S4TGUV7�5=UVW-<0?1X@?�YZ5 >�5 :�5=[V>

'"\*] ^�_a`cb*+(dfe-\*^hg�i�j�kI��b�d�'.l"�.��m��.`.n2o,l.�"��m���p"o q,qrq s0+&t=o'.\�]�^ _a`�b�+$dfe-\�^1g�i�j�kI� b*d�'"l.�"��m���`"nuo,l"�.��m���p.o=q,q,q s +ft=o '"\*] ^�_ p"b*+(dfe-\*^hg�i�j�kI��b�d�'.l"�.��m��.`.n2o,l.�"��m���p"o q,qrq s0+&t'.\�]�^ _ p.b�+$dfe-\�^1g�i�j�kI� b*d�'"l.�"��m���`"nuo,l"�.��m���p.o=q,q,q s +ft

Slide 12.1: Format of the ASCII configuration file

Page 219: Advanced KM Development

12.3 Config File actions 211

12.3 Config File actions

The following slides show the syntax and actions you can take on a con-fig file.

Å�� Ü(�+� * � � À�$��0����vÅ�� Ü(�+� * � � À�$��0����vw&x�y¿4/z �1{�| xf}[email protected],5��¥��0á | }Gx4c(ä|��Ïå {��0� c(ä��%g � f�f>f2�0x��

�� �7¦�����¤�¢oM�¥�+�¤�/�/¼©�,Î�¡��7¦�����¤�¢oM�¥�+�¤�/�/¼©�,Î�¡��� ���@A|;2��?��@�ED�;=��� �9� �9����� ���9� U :���@A|;2��?��@�ED�;=��� �9� �9����� ���9� U :�� ¯�«���'¡¥¼¤�/;���7²�� µ@2¯�«���'¬¥§¤�/;���7²�� µ@2AgentSetupAgentSetup�� U =@; �cL�K=���fIr��=MHA>?BL �u�����@?@A2��?��cDO;EFU =@; �cL�K=���fIr��=MHAE?@L �u�����@?@A2��?��cDO;EF�� U K>K �M��cLc ��EI¡�BA2�V?@L �u���U K>K �M��cLc ��EI=�@A2�V?@L �u����� ��� DOL�;>A.¢£��F�L�F��� DOL�;>A.¢£��F�L�F�� ¤�M�� ���c=¥��?@A2�O?���DO;>F¤�M�� ���c=¥��?@A2�O?���DO;EF

Slide 12.2: Syntax of a configuration variable

Page 220: Advanced KM Development

212 Configuration Variables

Û �q�(�!�� À $��0�J��vÛ �q�(�!�� À $��0�J��v¦1x�y¿4�z �h{�| x&}G~�y�z-,5��¥���á | }Px c(ä|��Lå {��§� c(ä��%g � f>f�f,�§x��

¨¨ ©«ª*�.2T�«¬­ª1®6¯�°©«ª*�.2T�«¬«ªh®6¯�°valval ±"² £¡�¡«�/¼¤�'¡�?�¡ �¥�+�¢�¥¼¦43�(­¤�/Ê©���+S,7¥§¢oM±"² £¡�¡«�/¼¤�'¡�?�¡ �¥�+�¢�¥¼¦43�(­¤�/Ê©���+S,7¥§¢oM

<<valval>>¨¨ ³«ª 2�ªT²�ªh® ¯c°³«ª 2�ªT²�ªh® ¯c°valval ±"² ���*/ �¡¢��´°±"² ����/ �¬¢��´°

valval ± ¨�£¡©­ª /§¥�+�¢M©�¨�(�¤�/K©���+± ¨�£¡©­ª /§¥�+�¢M©�¨�(�¤�/K©���+¨¨ �«�9�9ªT±-³G® ¯�°�«�µ��ªT±-³G® ¯�°valval ±"² ©�¦�'¡©�¦���¥§¢�¥§©�¦�¤�/�/r�I¤����6°±"² ©�¦�'<©�¦���¥§¢�¥§©�¦�¤�/�/r�I¤����6°

valval ± ¢Ë©V/¼¥�+�¢± ¢Ë©V/¼¥�+�¢¨¨ ¶&ª�©«·Oª1®6¯�°¶&ª�©«·Oª1®6¯�°valval ±"² ¤����¸°±"² ¤����¸°

valval ± ¥ ¨J¦�©�¦± ¥ ¨J¦�©�¦--�¡ �¥�+�¢��¬¦�¢ ¥¼¦p/§¥�+�¢�¡ �¥�+�¢��¬¦�¢M¥§¦p/§¥�+�¢

Slide 12.3: Syntax of the configuration actions

Å�� ��¹ � À�$��0�J��vÅ�� ��¹ � À�$��0�J��vº1x�y¿4�z �h| xf}P~�y�z-,"��¥���á | }Px c(ä|��Lå {.�§� c(ä��%g � f>f�f,�§x��

»» CommaComma--+k�¬«�¤�£¡¤�¢��¬�p/¼¥�+k¢+��¡«�¤�£¡¤�¢��¡�p/¼¥�+k¢»» 7T��,Τ�£¡�?©�¨7T��,Τ�£¡�?©�¨

\\'¨M�¤�£¡¤�'¬¢��¡£�+�¼}¤�/�+�©'¨M�¤�£¡¤�'¬¢��¡£�+�¼}¤�/�+k©

\\¦Lí�®�/§¥�+�¢+0½¦Lí�®�/§¥�+k¢�+0½¾¾ ¿ ¿ ¿@F�;>;.À;ÁH?þL�ÂOL�C�ÃB;>F�À;Â�L ÁV=@;tLcÄ�A>;¿ ¿ ¿@F�;>;.À;ÁH?þL�ÂOL�C�ÃB;>F�À;Â�L ÁV=@;tLcÄ�A>; --set()set()

Slide 12.4: Syntax of the configuration value

Page 221: Advanced KM Development

12.3 Config File actions 213

Å !��ß�+¿�$�����ß��.Æ0�ÈÇ �?�q��Ü�$ Þ !��q¿(��ß ¹ ÜJ���(�!ß�Å !��ß�+¿�$��?��ß��.Æ0�ÈÇ �?�q��Ü�$ Þ !��q¿(��ß ¹ ÜJ���(��!��FileFile

� É$ÊÌËÎÍ�ÏÌÐÒÑ­ÓÌÔÖÕ0×­Ø£Ù

Binary config file

Ú¥Û�ÜrÝ�Þ�ߣà¥ápconfig(“ REPLACE” ,” /A/B” ,” value” );

①①①①

②②②②

Slide 12.5: Modifying the Binary Configuration File I

Å !��ß�+¿�$�����ß��.Æ0�ÈÇ �?�q��Ü�$ Þ !��q¿(��ß ¹ ÜJ���(�!ß�Å !��ß�+¿�$��?��ß��.Æ0�ÈÇ �?�q��Ü�$ Þ !��q¿(��ß ¹ ÜJ���(��!��FileFile

� âãÊäÍ@Ï�ÐåÑDÓ�ÔÖÕ0×çæ configfile>

Ú¥Û�Ü,Ý�Þ�ߣà¥á

Binary config file

pconfig mycfg ①①①①

②②②②

________________________

③③③③

Slide 12.6: Modifying the Binary Configuration File II

Page 222: Advanced KM Development

214 Configuration Variables

Å !�����¿�$�����ß���Æ0�ÈÇ �?�0� Ü�$ Þ !��0¿(�}ß ¹ ÜJ�0�(�!ß�Å !��ß�+¿�$�����ß��.Æ0�ÈÇ �?�0� Ü�$ Þ !��0¿d��ß ¹ Ü��0�(�!ß�FileFile

èhé&êGë PatrolAgent -ì*íµî§ï¥ð -config <cfgfile>

Binary config file

Ú¥Û�Ü,Ý�Þ�ߣà¥á

________________________

②②②②

PatrolAgent - ñ Û£Ürò�ó -ò£Þ�ô�õrö ÷�ø-ù�ò£õr÷

úcû ü�û �1�C� � �%��ý ú ①①①①

Slide 12.7: Modifying the Binary Configuration File III

Page 223: Advanced KM Development

12.4 Useful configuration variables for development 215

12.4 Useful configuration variables for develop-ment

DevelopmentDevelopment

þ /AgentSetup/ÿÿ [<APPL>.[<INST>.]][<APPL>.[<INST>.]]defaultAccountdefaultAccount�� ������������ ������������������������������������� ��������������������������ÿÿ <APPL>.<APPL>.filterListfilterList�� ���������������������! #"%$#"'&)(��*����+������,��������������*�������- ."/$."%&0(�������+������,�� �����������132������4���+���������������!�����������������1�2������4���+���������������-�������ÿÿ <APPL>.<APPL>.filterTypefilterType

Slide 12.8: Useful Configuration Variables for Development

12.5 Security Settings in the Agent

12.5.1 defaultAccount

The agent uses the <APPL>[.<INST>].defaultAccount user to run pa-rameters, recovery actions, and application discovery procedures if anaccount is not specified for these commands. The default is patrol. Ifa hard-coded default other than PATROL is used, the agent issues awarning unless a valid encrypted password is provided for the account;for example, ”user1/encrypted password>.”

Page 224: Advanced KM Development

216 Configuration Variables

12.5.2 OSdefaultAccount

The agent uses the <APPL>[.<INST>].OSdefaultAccount user to runparameters and recovery actions for this application or application in-stances unless an account is specified for these commands. The defaultis NULL (use PatrolAgent’s defaultAccount).

12.5.3 OSdefaultAccountAppliesToCmds

If the flag is set to ”yes,” then menu commands that run against in-stances of this application will run as user specified by either :

<APPL>.<INST>.OSdefaultAccount or<APPL>.OSdefaultAccount

Otherwise, menu commands will run as the user that the consolelogs into the agent unless a explicit account is specified for the com-mand. The default is ”no” (don’t run as *.OSdefaultAccount).

À��0� ¹ Ü(�+��$ À����J�d�?��ß����?� �.Æq��Û3ßv���q�À��0� ¹ Ü(�+��$ À������(�?��ßk����� �.Æq��Û3ßv���q�

5/z®¦då�ç'6Ï, âdç~ f��¦��Ïã�ä76f�%â(ç 4qädãX�7ä78~�7å�æ99 //AgentSetupAgentSetup//:: <APPL>[.<INST>].<APPL>[.<INST>].defaultAccountdefaultAccount:: <APPL>[.<INST>].<APPL>[.<INST>].OSdefaultAccountOSdefaultAccount:: <APPL>[.<INST>].<APPL>[.<INST>].OSdefaultAccountAppliesToCmdsOSdefaultAccountAppliesToCmds

Slide 12.9: Security Settings in the Agent

Page 225: Advanced KM Development

12.5 Security Settings in the Agent 217

12.5.4 Determining Security Context (for %{username} and%{password})

The agent will walk the inheritance tree looking for security settings on

• Parameter

• Instance

• Application

If an agent configuration variable exist on each of the levels, theagent will use that configuration setting, otherwise the agent will checkif configuration was set in the property sheet before proceeding to thenext level.

If no security is defined, then the empty string will be returned (“”).

Page 226: Advanced KM Development

218 Configuration Variables

Page 227: Advanced KM Development

Chapter 13

Command Types

13.1 Command Types

Command types are a powerful but alas unintuitive mechanism of iso-lating specifics of execution of types of commands. Each KM has a set ofattributes called “Command Types” that can be set on a per-class basis.Command Types can be specified for application or computer classes orinstances via the ”Types of Commands” menu entry.

Once defined, the command types should appear on the option menuin the Console GUI for the ”Command Type” button when creating acommand. However, this direct usage of the Command Type is not rec-ommended, but it is better to use the name of a command type as thefirst argument to PSL execute or PSL popen in a PSL script. SamplePSL scripts might look like:

ret = execute("MY_CMD_TYPE", some sql script);

This use of command types in PSL execute or popen forms the basisof their use. In this way, they are often used in conjunction with globalchannels opened via PSL popen.

219

Page 228: Advanced KM Development

220 Command Types

L�!<; Þ !���� ���0�>= $��q���@?BA�� Þ AJ���0�J���L�!C; Þ !���� ���0�>= $��0���@?BA�� Þ AJ���0�J�0�

DD E ¸GF-H ¶ HJI ³JK�LNM F º µ�HJOQPJR · P�STS L ¸�IGUE ¸GF-H ¶ HJI ³JK�LNM F º µ�HJOQPJR · PJSVS L ¸.IGUWW XZY\[�]\^\_�`ZabXdc�edfgfXZY\[�]\^\_�`ZabXdc�edfgfWW eZ]\]\cihiXZeZ_ihiY\j.Xdc�edfgfeZ]\]\cihiX�ed_ihiY\j.Xdc�edfgf

DD k O L/l Hnmk O L/l HnmWW o\hia�`dXZ_p3]\eZa3eZ[�`Z_�`Zabq�r'suto\hia�`dXZ_p3]\eZa3eZ[�`Z_�`Zabq�r'sutWW

popenpopen()()WWexecute()execute()

Slide 13.1: How Command Types Are Created

vv w¿³ P K IxOdy�z�µ ¶ P · HJOO{H4|}H · y�F K P¹¸w¿³ P K IxOdy�z�µ ¶ P · HJOO{H4|}H · y�F K P-¸vv E |/F ¶JL Pwµ�F K P¹¸�OQP¹¸ µ ¶ P · HJO-O{H4|}H · y�F K P¹¸E |/F ¶JL Pwµ�F K P8¸�OQP¹¸ µ ¶ P · HJO-O{H4|}H · y�F K P¹¸vv ~ P/OZF · P�STS L ¸�I#µ ¶ P · HJOO K ¸��~ PGO�F · P�STS L ¸�I#µ ¶ P · HJOO K ¸��

Slide 13.2: Why Use Command Types

Page 229: Advanced KM Development

13.2 Command Type Features 221

Command Type At-tribute

Purpose

Command Template The command that is launched.Pre-Command Text Text that is sent to the standard input of

the launched child process, before the com-mand.

Post-Command Text Text that is sent to the standard input ofthe launched child process, after the com-mand.

No failure detection Do not kill the child process at all.Terminate if outputcontains

Kill the spawned child process if the re-turned output from the command containsthe specified text.

Kill process/Kill pro-cess group

Send the kill signal to the process or theprocess group.

with signal SIGTER-M/SIGINT/SIGKILL

The signal used to kill the process.

Table 13.1: Command type properties

13.2 Command Type Features

Command types offer a number of attributes. The full list is shown intable 13.1.

The three main fields are Command Template, Pre-Command Text,and Post-Command Text.

The Command Template is usually the primary command for execu-tion.

The fields related to killing the process, such as “Terminate if outputcontains”, are not usually used because the functionality offered is toolimited. Killing the process is usually handled explicitly rather thanusing these flags.

Page 230: Advanced KM Development

222 Command Types

Slide 13.3: Command type Features

13.3 Command Type Macros

Each of the command type fields can be literal text, but this is quitelimited. For more power there are macros that are expanded at thetime that the command is launched. The Command Template can usethe the macro’s as described in table 13.2.

The %{password} macro allows command types to access secure in-formation without making it available to the PSL code in general. Com-mand types are the only place where the password builtin macros isavailable to a KM. For example, a PSL get on the password variable inthe symbol table will fail returning the empty string.

The %{command} macro for command text is the text string thatcomes from the second argument to the PSL execute or popen call. Inthe case of directly launched commands using this command type, thisis the full command-text of a command explicitly typed as this commandtype.

Page 231: Advanced KM Development

13.3 Command Type Macros 223

Macro Name Expanded Result%{username} Username specified in application or in-

stance%{password} Password specified in application or in-

stance%{command} Command text; this is the text string that

comes as the second argument to PSL exe-cute or popen.

%{commandFile} Temporary file in which command is stored%{shell} Default shell of user running this command

(Note that this user is not the same useras the %{username}macro, since this useris an OS account and %{username} is anapplication account.)

%{fastShellStartFlags} “f” if shell is csh or tcsh; otherwise value isthe empty string.

%{shellflags} (OS/2 or Windows NT agents only) “/C” or“/K” depending on the command shell.

%{anything} User-defined macros can be specified, andare expanded based on the agent symboltree values from PSL set.

Table 13.2: Macro’s in command types

Page 232: Advanced KM Development

224 Command Types

Macro’sMacro’s�� �{��������d���+�������!������u�+�������������-�+�}��{������d�����+�������!������u�+�������������-�+����� �{����+�����%�+�������!������u����d���-�������/������{����+�����%�+�������!�����������d����������%�+����� �{�g���+�����+�����!�+����{�g���+�����+�����!�+��

argarg � ���+�0���+�d����u������ ���+�0���+�d����u����� popenpopen�� %{%{commandFilecommandFile ����������� � � � � � �+�����+�����+�����!������� � � � � � �+�����+�����+���� �{�g�� ���������!������d¡��J�� � �+�-� �!�� ������\¢�£#¤}����d��¥�{�g�� �d� �����!����d��¡��J�� � �+�-� �!�� ������\¢�£#¤}����d��¥�� %{%{fastShellStartFlagsfastShellStartFlags ��¦�§ �u¨ ¢��¦�§ �u¨ ¢ cshcsh//tcshtcsh))�� %{%{shellflagsshellflags ��¦�§g©�ª«����©�¬ ¨ ¢��+�-� ­�£#¤Z©���®�¯/°7¥��¦}§g©�ª«����©�¬ ¨ ¢��+�-� ­�£#¤Z©���®�¯/°7¥�� �{�g���­+�� � �-±����!�+��­�²+�+�d� ��³-� ���u �+�-�%�+�����d��¢u¥!� �}�u ���+±+����u��{�g���­+�� � �-±����!�+��­�²+�+�d� �+³� ���u �+�-�%�+�����d��¢u¥!� �}�u ���+±+����u�namespacenamespace

Slide 13.4: Command Type Macro’s

Page 233: Advanced KM Development

13.3 Command Type Macros 225

13.3.1 Using the %{command} Macro

The %{command} macro is very special in that its presence changes thebehavior of the command type in a major way. If the Command Tem-plate contains the %{command} macro, then the %{command} macroexpands out to become the command text. Neither pre-text nor post-textare used if there is a %{command} macro in the Command Template.Hence if the Command Template uses %{command}, pre-text and post-text are pointless. An example of a simple send-to-shell command typeis:

COMMAND TEMPLATE: %{shell} %{command}

In this example, pre-text and post-text are irrelevant and ignored.This means that using the %{command} macro in the Command Tem-plate has limited value. This usage only achieves a wrapping of thecommand inside another command, but does not allow the use of pre-text or post-text to send input to the command.

´´ prepre-- µ µ¶P/OZF�F!H4·/F L-¶ H K�¸ ¸�P ¶ HJIº¹�¹µ µ¶P/OZF»F-H4·/F L-¶ H K�¸ ¸�P ¶ HJIº¹�¹´´ H4· L S µ ´ Hn¼H4· L S µ ´ H½¼¾¾ ¿¶ÀÂÁÃÁÃĶŶÆÈÇ}É�ÁÃÊ*Ë»Ä�Ç�ÉÌɻͶÄ�ÁÃÊ�Ë»É�ÎNÏ¿¶ÀÂÁÃÁTÄ�ŶÆÈÇ�É}ÁÃÊ*˻ĶÇ}ÉÌɻͶÄ�ÁÃÊ�Ë»É�ÎNÏÐÐ

/bin//bin/kshksh -- Ñ%ÒnÓgÑZÔ4Õ�Õ�ÖZ×\ØJÙÑ/ÒnÓgÑZÔ4Õ�Õ�ÖZ×4ØbÙ (KSH)(KSH)ÐÐ Ò«Ó�ÑZÔ\Õ�Õ.Ö�×\ØbÙÒ«Ó�ÑZÔ\Õ�Õ�ÖZ×\ØbÙ (UNIX)(UNIX)ÐÐ/bin//bin/cshcsh -- Ú#ÒnÓgÑZÔ4Õ�Õ�ÖZ×\ØJÙÚ#ÒnÓgÑZÔ4Õ�Õ�ÖZ×4ØbÙ (DETACHED)(DETACHED)

¾¾ ÛÝÜ�Þ�ß�Þ«àÌá�â�ãJäCäæåJç�è#é/êæëbç�èìåbß�íJî�äæÞ�ç�ï/ðgãbßÛÝÜ�Þ�ß�Þ«àÌá�â�ãJäCäæåJç�è#é/êæëbç�èìåbß�íJî�äæÞ�ç�ï/ðgãbßÞ�ñJÞ�â�î�ï�Þ�ògó/ãbßÞ�ñJÞ�âî7ï�Þ�ògó/ãbß popenpopen()()

Slide 13.5: Using the command macro

Page 234: Advanced KM Development

226 Command Types

13.3.2 Not Using the %{command} Macro

The most common use of commands is without the %{command} macro.The absence of the %{command} macro in the command template (andalso without the %{commandFile} macro), causes more useful behavior.There is no expanding the command text into the %{command} macroas this is now obviously impossible as there is no such macro in thecommand template. The command text, which is sent as the secondargument to the PSL popen or execute function, is now piped to thecommand’s standard input. Only the Command Template specifies theexecuted command.

For example, let us make a command that executes a SQL scriptagainst an interactive database command :

tool .ret = execute("MY_SQL", "select * from my_table;");

For this to operate correctly, say in Oracle, we need this SQL com-mand in the second argument to be passed to some interactive com-mand. In the Oracle case we could treat “sqlplus” or “svrmgr” as com-mands that take SQL scripts as input. This would lead us to use thefollowing definition of the “MY SQL” command type:

COMMAND TEMPLATE: sqlplus

Now, when the PSL execute statement runs from above, the agentwill execute the command “sqlplus”. It will then send the SQL scriptthat is the second command text argument to PSL execute, down tothe standard input of sqlplus. In theory, sqlplus will then execute theSQL command it receives, and return the output. However, if you knowOracle, you know that this example does not yet actually work. Thereare a few problems.

Page 235: Advanced KM Development

13.3 Command Type Macros 227

NOT%{%{commandFilecommandFile}}

ôõ�ö7÷�øô�õ�ö7÷�ø-- ù�ú�û{û¶ü�ý�þ�ÿ ø�� ÿ ������ø ý�þ�ÿ�úù�ú�û{û¶ü�ý�þ�ÿ ø�� ÿ ������ø ý�þ�ÿ�ú stdinstdin�õ�� úû¶û{ü�ý�þ�� ø û� �� ü�ÿ ø�������ø��ø ù���ÿ ø þ��õ�� ú�û¶û{ü�ý�þ�� ø û� �� ü�ÿ ø�������ø��ø ù��bÿ ø þ�õ ü ÷���� ú�� ø���ø ù���ÿ ø���� ú ÷��õ ü ÷���� ú�� ø��ø ù���ÿ ø���� ú ÷ popenpopen

����������ø ý�þ�ÿ�ú����������ø ý�þ�ÿ�ú stdinstdin�õ�ö ú � ÿ��õ�ö ú � ÿ -- ù�ú�û{û{ü�ý�þ�ÿ ø�� ÿ ������ø ý�þ�ÿ�úù�ú�û{û{ü�ý�þ�ÿ ø�� ÿ ������ø ý�þ�ÿ�ú stdinstdin H4· L S"!$#+Hn¼H4· L S"!$#+Hn¼

%%precommandprecommand &�')(*&,+&�')(*&-+.,/�02143$5�.-/6071�8-92:;0=<�3$5�>-9?/�/A@CBD1DE-<�F7/�0?G�G H-07:JI�I K.,/�02143$5�.-/6071�8-92:;0=<�3$5�>-9?/�/A@LBM1DE-<�F7/�0?G�G H-07:JI�I Kconnectconnect localhostlocalhost%% N�O*PQP$R�S*T &�' PVU*W�R &�'X+N�O*PQP$R�S*T &Y' PVU*W�R &�'X+ PatrolCliPatrolCli%%

postcommandpostcommand &Y'�(=&,+�')(*ZY&&Y'�(=&,+�')(*ZY&

Slide 13.6: Not using command or commandfile

The first problem is the sqlplus requires a username and passwordsubmitted before it will run a SQL command. We need to extend ourcommand type to use the %{username} and %{password} macros tosecurely submit these to the standard input of sqlplus before sendingthe SQL script.

Secondly, sqlplus will also produce a lot of spurious output that wemight not want to see in the result. This is more easily solved by usingthe –s flag to make sqlplus go into “silent” mode and suppress promptoutput.

Thirdly, there is another hidden problem in that sqlplus does not ac-tually exit after running a single SQL script. This would mean that,assuming we fixed both other problems, the call to PSL execute wouldstill hang indefinitely because it is waiting for the sqlplus process todie. We could use PSL popen to open an interactive channel, read theresulting output via PSL read, and then kill the process via the cor-rect arguments to PSL close. However, it is simpler to ensure that thesqlplus process receives an “exit;” command after the SQL script. Wecould either explicitly add “\nexit;\n” to our PSL execute call, but itis better that we place the exit statement in the command type itself,rather than having to remember it for every call to PSL execute.

Page 236: Advanced KM Development

228 Command Types

So the question is how to add the username and password before thecommand text, and the exit statement after the command text. Fortu-nately, this is exactly why a command type has pre-text and post-text.This example above shows that the command text is sent to the com-mand’s standard input. Actually, the full string sent down the pipe tothe sub-process’s standard input is the concatenation of the pre-text,command text, and post-text. If there is pre-text or post-text that arenon-empty strings, then some extra newlines are added. A newlinecharacter is added after the pre-text, after the command text, and af-ter the post-text (at the end). The above special command type macrosare expanded in the pre-text and command template but not the post-text or command text. If there is no pre-text or post-text, the commandtext is sent down the pipe, followed by a newline (to flush). In summary,the string sent to standard input is:

• Both pre-command text and post-command text

PRETEXT\nCMDTEXT\nPOSTTEXT\n

• Pre-command text but not post-command text

PRETEXT\nCMDTEXT\n\n

• Post-command text but no pre-command text

\nCMDTEXT\nPOSTTEXT\n

• Not post-command text nor pre-command text

CMDTEXT\n

Therefore we can extend our example command type to handle secu-rity login, and to terminate the session afterwards. The new attributesto the “MY SQL” command type should be:

COMMAND TEMPLATE : sqlplus --sCommand}PRE-COMMAND TEXT : %{username}/%{password}POST-COMMAND TEXT: exit;

This is a typical practical use of command types. A command typewithout a %{command}macro is typically used for establishing databasesessions. The command template is used to spawn the database sessioncommand-line program. The pre-text is used to send a session connec-tion or login sequence using the %{username} and the %{password}special macros. Since these account details are on standard input rather

Page 237: Advanced KM Development

13.3 Command Type Macros 229

than command-line arguments the password does not show up in pro-cess detail ”ps” output for the spawned command. The post-text is usedto specify a command to exit the session if this does not happen bydefault. In this way, the command text can be a SQL query on thedatabase, without having to specify any of the login/logout protocol tothe database server.

13.3.3 Using the %{commandFile} Macro

The %{commandFile} macro is also very special and expands out tobe the name of a temporary file, as created by the standard tmpnamcall. Under UNIX this is usually a filename starting with ”/tmp/”. Thetemporary file is also changed to be owned by the user account andchanged to permissions 0500 under UNIX platforms. The presence ofthe %{commandFile} macro in the Command Template causes the com-mand text (i.e. that which would have usually been expanded in the%{command} macro) to be written to the temporary file. Macros areexpanded in the command template and the command text. Note thatpre-text and post-text are not written to the file, and in fact have noeffect if %{commandFile} is used. This can easily be considered a bugor a feature, as you please. Note that whenever the command finishes,the temporary file will be automatically removed by the agent.

Note: Command Types cannot use both %{command} and %{commandFile}and will receive a runtime error from the agent, and any com-mands using that command type will not execute.

Page 238: Advanced KM Development

230 Command Types

commandFilecommandFile}}[[ prepre-- µ !¶PGO�F�F!H4·GF L]\ H K+¸]^ P \ HJIù�¹µ !¶P/OZF�F!H4·GF L]\ H K�¸]^ P \ HJIù�¹[[ _Q^ I L]\J¸�` S H ^ F K OQO LXa HJI K�^ºL R K #+H M_Q^ I L]\J¸�` S H ^ F K OQO LXa HJI K�^ºL R K #+H M

tmpnamtmpnam()”()”[[ H4· L Sb!$#+Hn¼H4· L Sb!V#�Hn¼

cc ¿�À«ÁÃÁÃĶÅ�Æ Ç}É�ÁÃÊ*Ë»Ä�Ç�ÉÌÉ»Í�ĶÁÃÊ�Ë»É}Î Ï¿¶ÀÂÁÃÁÃĶŶÆÈÇ}É�ÁÃÊ*Ë»Ä�Ç�ÉÌɻͶÄ�ÁÃÊ�Ë»É}Î Ïdd

perlperl %{%{commandFilecommandFile}}ddawkawk -- egfihegfjh commandFilecommandFile k4fjhkCfih myfilemyfile}}

Slide 13.7: Using the commandFile macro

13.4 Command Types and UNIX Shell Issues

If you do not include any ’%{shell}’ macro in your command templatethen the agent will attempt to execute the command directly, withoutpassing it to a shell for tokenization, quote handling, backslash han-dling, I/O redirection handling, piping, etc. This means that if you wantto use piping or redirection, etc, then your command template shouldhave a prefix of %{shell} or actually :

%{shell} -%{fastShellStartFlags} # UNIX%{shell} %{shellflags} # Windows

Without all of the features provided by the shell you can’t do a greatdeal but it does allow you to execute commands directly, rather thanwasting memory/process slot on executing a shell, and then having theshell execute your command. So there are obvious tradeoffs.

This does have an important advantage: using a newly defined com-mand type without a %{shell} macro is more efficient than choosingOS command type for a command or PSL execute/popen call, since the

Page 239: Advanced KM Development

13.5 Command Types in (pre)discovery 231

builtin OS type will spawn a shell to handle the commands. Hence theseextra shell processes can be avoided by using a command type instead.

The tokenization (parsing of the command string into a list of argu-ments) performed by the agent is very, very simple. It splits the com-mand string into a argument list based only on whitespace. So you can’thave a token ’”a b c”’ and expect it to be split into one argument, ’a b c’.What you will actually get is three arguments: ’”a’, ’b’, ’c”’. For example,if you have a command type defined as:

COMMAND TEMPLATE: /bin/cat < %{commandFile}

This is erroneous since the ”cat” command will get two arguments of”<” and the filename, and will try to output a file named ”<”. Instead, itis necessary to use %{shell} here to ensure that the redirection occurscorrectly.

COMMAND TEMPLATE: %{shell} /bin/cat < %{commandFile}

13.5 Command Types in (pre)discovery

A command type defined on application level (and not on computer classlevel) has to run in context of an instance of this application.

This instance should be specified in the 3rd argument of the executefunction, in case you are using the execute function with such a com-mand type in a discovery script. When execute is called in an infobox,menu command, parameter or recovery action, PATROL will find thenearest ancestor instance himself. However, since discovery is ran onapplication level, there is no way the agent can determine the instanceyou would like to use...

In case you want to run execute() after you have already created aninstance, you can specify that instance. For example, a discovery scriptlike below will work

...create(inst,inst,OK);...execute(cmdtype,cmd,inst);...

In case you are trying to discover which instances you should createfor your application class (for example CHILD.km), you can define the

Page 240: Advanced KM Development

232 Command Types

command type in another KM that can even possibly be the parent ofCHILD.km (for example PARENT.km) In this case, PARENT.km shouldalready have at least one instance ... for example, PARENT/TOPLEVELcould be the unconditionally created parent instance.

Now in discovery of CHILD.km, you can call execute() like this :

execute("CMDTYPE","cmd","/PARENT/TOPLEVEL");

Another option (not really advised) would be to create an invisibleinstance of your application (unconditionally). In your discovery youcan do the following to create an invisible instance. Note that the name”invisible” is not important, but the fact that this create statement onlyhas one argument is !

if (! exists("invisible")){

# Create invisible objectcreate("invisible");

}

Now every execute can use the ”invisible” as the instance to providethe context.

execute(cmdtype,cmd,"invisible");

Page 241: Advanced KM Development

Chapter 14

Global Channels

14.1 Introduction

The use of a PSL global channel is a design advantage for a KM wherean external process is used to access the application.

For such applications the least performance-effective method is torepeatedly launch it via PSL system or execute to collect each query.The more effect method is to use PSL popen() to create a local channelto the executable, use PSL write() to send commands to the executable,and to use PSL read() to get data from the application. This local chan-nel allows repeated commands to be sent to the executable, and permitsthe channel to stay open, thus avoiding the cost of process spawning. Ifonly a collector parameter is using the channel, it can remain a localchannel.

If more than one PSL process needs to get information from or to theapplication, this is not efficient. A local channel can be accessed onlyby the PSL prosess that spawned the child via the PSL popen function.In this case the more performance effective approach is to use the PSLshare function to convert the local channel to a global channel. Theglobal channel idea involves only creating a single child process.

14.1.1 Global Channels

A global channel is typically a pipe into an interactive process. Thischild process can be as simple as a system command shell, a command-line tool or a self-written application.

The use of PSL global channels is effective for performance improve-

233

Page 242: Advanced KM Development

234 Global Channels

ment only when the required conditions arise involving multiple PSLscripts and multiple child processes. The channel is an internal agentdata structure and has no actual physical runtime presence on the ma-chine.

The use of the global channel has a performance advantage in thatit allows one child process to be used by multiple PSL processes.

Creating Shared Channel

Once you have created a channel and you want to use it in multiple PSLprocesses, the process that created the channel will have to share it.

Using the share() Command

Sharing a channel means giving it a name and placing that name inthe PATROL Shared Memory space from the VM (instead of the processmemory area). This process is done with the share() command, and itdoes all of this for you.

When using shared channels, only one subprocess will answer allrequests from a number of PSL processes. This can be very good forperformance (applied to a KM that works on Oracle, this can mean oneconnection per Oracle instance, instead of one connection per parameterin the KM).

Share popen()

The slide shows an example of how the popen() and share() commandworks on the host OS when you execute the command :

1. Process2 popens to FTPCMD with arg: prc2cmd.

2. The channel is defined locally in the PSL processes memory.

3. After the share, the share name becomes known globally and pro-cess3 can use it.

14.1.2 Shared Channel Locking

Since multiple processes can occur simultaneously over a shared chan-nel, it can be desirable to introduce channel locking in your KM design.Sometimes it is not harmful if a command is messed up in the channel,

Page 243: Advanced KM Development

14.2 Channel Example 235

and mostly you can detect that this mess-up occurred when you readthe output of the channel. In some cases, it is not allowed to happen. Ifsuch is the case, you will have to lock() the channel.

When you lock() a channel, it will be locked for a certain PSL pro-cess. When you implement locking, you normally lock the channel be-fore writing to it; and you unlock it after you read the output from thechannel.

If another process wants to write to the channel, it waits until it canacquire a lock on the channel (when the process occupying the channelunlocks it). If no process is using the channel at the point of request,it will immediately get the lock. You will also have to implement time-outs on the lock so that a process will not be able to get the channelfor an infinite time. This will block the channel, and your KM will stopresponding.

Be careful when using shared channels in menu commands. Theuser is used to getting immediate feedback when executing a menu com-mand. If the execution goes over the same channel that you’re monitor-ing, a user issuing many menu commands will influence the monitoringpart of your KM (if the user gets the lock all the time). Another possi-bility is that the user might not get the lock at all (or within an accept-able time interval). The user’s perception will be that the KM performsbadly; therefore, it’s advisable to execute menu commands as one-timecommands.

14.2 Channel Example

Although channels are quite obvious to work with, it seems that a lotof developers find it difficult to get started with them. The exampleshown below doesn’t only show how to create channels, but also how youcould use channels to talk to other processes and do something useful.This example will pass a job where extended regular expressions areneeded to PERL. The two programs below work in tandem and talkover a channel.

PSL Program

function chan grep(channel, pattern, text){

local filter , eot , len , data;

Page 244: Advanced KM Development

236 Global Channels

# Used by the perl scriptfilter ="\n@#!FILTER!#@";eot="\n@#!EOT!#@\n";

if ( chan exists(channel)){

# Make sure noone will use the channel while we arelock("chan_grep_".channel);

# Write the filter definition , the text and the EOT# message. It would be possible to have multiple# filter conditions# But you will need to learn regular expressions.write(channel,filter.pattern."\n".text.eot);

# After EOT, perl script will return the length of the outputlen=trim(readln(channel),"\r\n");

# If there is more than 0 to read, get it ...if ( len>0){

data=read(channel,len);}

# Free the lockunlock("chan_grep_".channel);

}

return(data);}

chan=popen("OS","perl /tmp/xxx.pl");

text="1: aaa bbb ccc\n2: aaa xxx ccc\n3: aaa bbb ccc\n";

output=chan grep(chan,"xxx",text);print("\nOutput 1 =".output);

output=chan grep(chan,"bbb",text);

Page 245: Advanced KM Development

14.3 Channel Pitfalls 237

print("\nOutput 2 =".output);

output=chan grep(chan,"xyz",text);print("\nOutput 3 =".output);

close(chan);

Perl Program

$|=1;

while (<STDIN>){

if (/ˆ @#!FILTER!#@\s∗(.∗)/){

$filter =$1;}elsif (/ $filter /){

$output.=$ ;}elsif (/ˆ @#!EOT!#@/){

print length($output)."\n".$output;$output="";

}}

14.3 Channel Pitfalls

14.3.1 Shared channels not closed

If a KM is unloaded, the shared channels that were opened by thatKM will remain open. Therefore it is a good coding practice to see ifa certain ”share” already exists when the channel is established. It ispossible that the KM was unloaded and reloaded. Since it is not possibleto clean up at unload time, the KM should at least clean up at reloadtime.

Page 246: Advanced KM Development

238 Global Channels

14.3.2 Channel synchronization

Let’s fist explain the problem with channel synchronization . For exam-ple : you are using popen(), read() and write() to simulate an inter-active telnet session and have a function (below) which submits a com-mand to the telnet session and returns the response. Once the channelis open, you call this function several times in succession.

function mcomm(channel,command){

write(channel,command."\n");output=read(channel);return(output);

}

a=mcomm(handle,"echo apple");b=mcomm(handle,"echo banana");c=mcomm(handle,"echo pear");

Normally you would expect that

a = appleb = bananac = pear

What you might see is :

a =b = applebananac = pear

or

a =b =c = applebananapear

Definitely this is an indication about a synchronization problem inthe channel communication.

What you want to do is force read() to wait but also allow for thecase where the submitted command may not return any output.

Page 247: Advanced KM Development

14.3 Channel Pitfalls 239

As with any component that communicates with another component,you have to define some type of protocol.

By adding a minor convention to your code you can make the commu-nication more stable. The ”trick” is to wait until you get a terminationsignal... (In this case a very bizarre piece of text). Of course the end-of-output could also be signalled by a prompt or something else. If thesender can tell you how many bytes it will send, you could determinethe end- of-output by counting the number of returned bytes. One of thepossible ways of getting it done is shown below :

function mcomm(channel,command){

local data,output;output="";term="@@@_THE_END_@@@";term cmd="echo\necho ".term."\n";

write(channel,command."\n".term cmd);

while (data=read(channel)){

output=output.data;if ( grep("ˆ".term."$",output)){

output=replace(output,term."\n","");last;

}}return(output);

}

Depending on the product you are talking to, there might be otherand better solutions.

Page 248: Advanced KM Development

240 Global Channels

Page 249: Advanced KM Development

Chapter 15

Events and state changeactions

15.1 Introduction to event

15.1.1 Agent generated events

To understand the PEM architecture, it is important to realize thatthere are a number of ways to trigger an event.

Once an event is triggered, the PATROL Agent feeds a snapshot ofthe event to the PEM. The PEM then matches the information passed onby the agent against an event catalog (by default, the Standard EventCatalog). Criteria for type of event, as well as the extraction of details,are matched against this catalog, and an event type is established.

In addition to the Standard Event Catalog, the PATROL DeveloperConsole can define custom event catalogs. The Standard Catalog de-scribes types of events, and the PEM pushes any event from any perfor-mance area through this catalog. Custom events are sent from customtriggers, also user-definable from the Developer Console, and pushedthrough the PEM. The PEM then forwards all details as one event file,complete with numeric id, to the Event Repository.

The Event Repository is a definable amount of memory dedicated tobuffering the most recent events noted by the PATROL Agent and PEM.PEM also forwards these event files as messages to any interested PA-TROL Console via the PATROL API, as well as any registered SNMPconsole via an SNMP trap. Once the Event Repository fills to the max-

241

Page 250: Advanced KM Development

242 Events and state change actions

imum level, it writes itself to a circular file of the same size, called theEvent Log.

When an event occurs, the state change is propagated up throughthe object hierarchy (in the case of alarms and warnings). The agentuses this means to notify you visually on the console. At the same time,the agent logs the event details, which it stores as a circular log file.

The agent sends the most recent event entries to the event cache atyour console. You can dictate how much temporary disk on your consoleyou will devote to the cache using the miscellaneous option on the UserPreferences Property Sheet.

The rest of the events are stored in the log file at the agent. Youquery this file when you run View>Event Repository Statistics... fromthe Console Menu. You can also query the log file at the agent using theFilter button in Filter Mode.

15.1.2 KM generated events

Out-of-the-box events are automatically triggered by changes in stateof objects. PATROL does not issue events from recovery actions withinparameters, but rather hard codes them into the product. So, with thismodel, you get coverage from the first time you start up PATROL. IFsomething is going wrong, PEM sends an event. If something comes outof ALARM (is going right), PEM sends an event. If someone attachesto an agent or runs a command remotely on an agent, PEM sends anevent.

What if you want to specify what constitutes an event in your envi-ronment? You can trigger events with one simple PSL command calledevent trigger(). If a performance area breeches a threshold; you canuse the PSL command from within a Recovery Action (which is initiatedimmediately upon notice of the ALARM or WARNING).

If one event occurs, and you wish to issue another based on other con-ditions at the time of record, you can issue the PSL command throughan existing event type.

If you wish operators the ability to manually issue events as troubletickets to the OEM trouble ticket system, you can use the PSL commandas a PATROL Menu Command on the PATROL Console.

Page 251: Advanced KM Development

15.2 Event Catalogs 243

15.2 Event Catalogs

The PATROL Standard Event Catalog gives you the broadest event cov-erage possible. No matter what KM you purchase, or develop on yourown, the Standard Event Catalog ensures that you get a basic set ofevents with the default triggers.

All KMs will have their ALARMs, WARNINGs, and other defaultevents passed through the Standard Event Catalog. No matter whatthe KM, or individual performance area within that KM, certain eventswill always be passed along as a type from within the Standard Catalog.For example, an Event Class 11 from the Standard Catalog is definedloosely as any change from OK to ALARM, with a corresponding Re-covery Action. Any event, whether from ORACLE, the CPU area of thePATROL KM for Unix, or a custom KM, that matches the criteria willfall under Event Class 11. This creates a small problem in providingevent specific help, troubleshooting, or other documentation as part ofthe event generation.

15.2.1 Custom Event Catalog

However, where such event specific documentation is desired, a customevent can be established. Like any other attribute of a KM, events canbe added individually to a pick list. This pick list then becomes a Cus-tom Event Catalog. Each one of these custom events can then define onespecific event, and document details concerning the automated responsefrom PATROL, or the desired response from the end-user/operator. Thiscustom event is generated upon the trigger you choose, to ensure it isonly created if the specific situation arises.

15.2.2 Elements of an Event Class Dialog

Event Type : Default type is the type of event (warning, alarm, etc.).

Life expectancy : has to do with whether or not the event entry willbe written into the circular log file from the memory block.

SNMP Support : allows you can select if the event is to be sent as anSNMP trap to another 3rd party console or trouble ticket system.

Escalation Period : defines if the event is not acknowledged, closedor deleted in the time specified here, the commands you enter in

Page 252: Advanced KM Development

244 Events and state change actions

this field will execute. Use this only if PATROL Consoles will bethe component from which you assign ownership.

Notification Command is executed as soon as this type of event islogged. Use this for your automated solution, if any.

Acknowledgement Command is triggered when an end-user physi-cally selecting this event when logged, and designating it as “ac-knowledged”. Again, this is dependent upon the PATROL Consolebeing responsible for ownership and closure.

Expert Advice/Description You also have the ability to enter expertadvice. This field can be passed along to other OEM systems. De-scription is also customizable from this Property Sheet and alsopassed along to other OEM systems.

The steps below demonstrate how to create a custom event cata-log. In this example, let’s assume that you created a parameter calledCPUNumProcs in the NT CPU application class, and now you need tobuild an event catalog and trigger a recovery action for the CPUNumProcsparameter

1. From the KM tab tree view, expand the [Application Class] folder.

2. Expand the [NT CPU] application class.

3. Expand the [Global] folder.

4. Right-click Event Catalog and choose New. The Event Class prop-erty sheet appears.

5. In the Event Type field, select ALARM.

6. In the Name field, type “CPU Working Too Hard”.

7. Select the [Description] tab. In the Description area, type “I’mworking too Hard!!! There are %s process running and my CPUutilization is %s.”

8. Click the [OK] button.

Page 253: Advanced KM Development

15.2 Event Catalogs 245

15.2.3 State Change Actions

State change actions are console-side actions that will be taken in casean object changes state. Below you will find a list of facts about statechange actions.

• State change actions can be defined on computer level and appli-cation (actually instance) level.

• State change actions are executed by the console and will only beexecuted when the computer/instance changes state.

• If you defined a state change on instance level, then if one param-eter of your instance parameters goes into alarm (which changesthe state of the instance to alarm), the alarm state change actionwill be fired off. If a bit later another parameter will go into alarm,this will not cause the state change to be re-triggered, because theinstance will not change its state again!

• If you define a state change to a computer class, only computer ob-jects will trigger the action. Also, computer objects don’t get theirstate from parameters, even when everything is set to propagate.They get their state directly from the parents of those parameter’sinstances (applications). Therefore, there’s no ’direct’ way for acomputer class to know which parameter put it into alarm.

• State changes can be OS commands only.

• State change actions are very different from recovery actions, whichare associated with parameters and event notification actions, whichare associated with event. The agent executes both recovery ac-tions and event notification actions.

• State change actions do not have an ”auto repeat until...” possi-bility, but that doesn’t mean this functionality can not be devel-oped by you. For example: on ALARM/WARN state change, in-voke some kind of OS process such as a C program, perl script, OSscript, etc. which would continuously run and periodically takethe desired action. You would then use the OK state change toexecute another OS command which would stop the ALARM statechange action.

Page 254: Advanced KM Development

246 Events and state change actions

macro descriptionAPP TYPE Application name (e.g., ORACLE)

COMP STATUS Computer’s state (e.g., VOID, OK, WARNING)COMP TYPE Computer type (e.g., SOLARIS)

CON INFO Network connection information (e.g., host name or net address)CON STATUS Network connection state (e.g., OK, Soft Problem)

CON TYPE network connection type (UDP or TCP)DISPLAY NAME Host name where the console is displayed

HOME Home of this parameter, task, or commandHOSTNAME Host name

INSTANCE ID Instance id (e.g., ORACLE SID)LANGUAGE The language to use in soundPASSWORD User’s password

SID Instance id (e.g., ORACLE SID)STATUS Status of computer or task

TIME Current time of dayUSERNAME User’s login name

VOLUME Sound volumeWORST CHILD Worst child (parameter or instance) running on this object

Table 15.1: Macro’s in state change actions

• If you define state change actions on a global level, and addition-ally on a localized level (for a specific computer/instance) then boththe global and the local state change action will fire off in parallel.

In a state change action, following macro’s can be used :These macro’s will be subsituted prior to executing the OS Com-

mand.echo %{HOSTNAME}

15.3 PatrolCli PSL execute

The PatrolCli utility is one of the programs that is almost completelywritten on top of the event subsystem. PatrolCli also allows you to ex-ecute PSL, but there is a limitation in the size of the PSL script that itcan execute. However, if you understand how the agent executes noti-fication actions, we will see that we can overcome that limitation. The

Page 255: Advanced KM Development

15.3 PatrolCli PSL execute 247

sympthom of the problem is that only the first line of a multiline PSLscript will be executed (the rest seems to be ignored). In this section wewill investigate the problem and find a solution for it.

Let’s say you want to execute a PatrolCli command that will returnall loaded applications. Code to do that is :

applications=get vars("/","subnodes");

foreach appl (applications){

applpath="/".appl;if ( get(applpath."/__type__") == "APPLICATION"){

ret data=[ret data,applpath];}

}# Now we want to return ret data .

When you would trace the remote PSL process that is launched, youwould see that actually all lines will will execute, but you will only getthe result of the first line. Which is :

applications=get vars("/","subnodes");

The reason for this is that your execpsl is actually being executed inthe RemPsl standard event’s notification action. The code in the RemPslstandard event notification action is basically:

# This command assumes that event arguments are separated by tabxxx pem=%{EV ARG1}event trigger("0","Result","INFORMATION",

"6",xxx pem,"%{EV_ARG2}");

The first line in the RemPsl standard event notification action willcause the execution of your script since a replacement of %{EV ARG1}will occur with your PSL script before compilation and execution.

This will thus result in

xxx pem=applications=get vars("/","subnodes");

foreach appl (applications){

applpath="/".appl;... etc ...

Page 256: Advanced KM Development

248 Events and state change actions

that means that only the result of first line will actually be passedback through the event trigger().

A way to execute multiple lines and get the result of what you wantit to be is by assigning the result to xxx pem yourself in your script.That means the last line should be :

# Now we want to return ret data ...xxx pem=ret data;

Another (simple) example to this would be

a="hello";xxx pem="a.world!";

Could be executed like this :

execpsl "0;\na=\"hello\";\nxxx_pem=a.\" world!\";\n"

And will result in the following script to be executed in the notifica-tion action:

xxx pem=0;a="hello";xxx pem=a." world!";event trigger("0","Result","INFORMATION",

"6",xxx pem,"%{EV_ARG2}");

Page 257: Advanced KM Development

Chapter 16

PATROL and SNMP

16.1 SNMP

The PATROL Agent has full agent-side support of SNMP, including MIBbrowsing and trap forwarding and receiving. These features are avail-able via PSL and partially via the PATROL MIB. The agent supportSNMP v1 and v2 except the getbulk functions.

The PATROL 3.2 and greater releases the agent now has only a sub-agent contained in it, and can talk to the separate master agent processor can talk to other master agents as required. This was done to elim-inate the duplicate master agents that often resulted in the use of the161 and 1161 ports.

16.1.1 Master Agent

One of the common issues with the master agent is how to tell if itis running. Some common errors message associated with the masteragent not running are:

SNMP.SNMP Command, Line# 11: TRACE: ASSIGN settings = ‘SNMPsupport is not active.

Or in the event log: ”Patrol SNMP Sub-Agent connection failed -Make sure SNMP Master Agent is running.” message in Agent ErrorLog when Patrol agent starts up.

To check that the master agent is running you can do the following:

• Check if the Agent variable /snmp/agent auto start is set to ’yes’.

• Check the parameter that starts up the SNMP subagent is active.

249

Page 258: Advanced KM Development

250 PATROL and SNMP

• Check if the process snmpmagt is running. If this is not running,the master agent is not started.

• If you already have an SNMP agent on the box, the master agentwill not be able to bind to port 161. This port is used whenever anSNMP manager wants to get info from any SNMP subagent do anetstat -a and check for processes that are bound to ports 161 or1161 (8161).

• To find out which port the master agent will bind to, look in the$PATROL HOME/lib/snmpmagt.cfg file. You might want to changethis number to something else (8161 for example) to see if the mas-ter agent will start on a different port.

Example of an snmpmagt.cfg file:

COMMUNITY publicALLOW ALL OPERATIONSUSE NO ENCRYPTION

TRANSPORT ordinary SNMPOVER UDP SOCKETAT PORT 161

In every Computer Class, you will find an SNMPstart parameter.When this parameter is disabled, the SNMP master agent will not startanymore.

To disable the parameter (from an NT Console), just selectComputer Classes ⇒ ALL COMPUTERS ⇒ <Your OS> ⇒ Global

⇒ Parameters ⇒ SNMPstart

16.1.2 Sending Traps

Another common question is how do I send traps form PATROL to aSNMP manager.

By default the agent will send the traps. If you want to make thesnmpmagt send traps you have to specify additional configuration (trapdestinations in the snmpmagt.cfg) and enable patrol for this by settingthe configuration variable ”/snmp/TrapConfTable” to ”yes”.

This PSL two-liner will fire a trap from the agent to a system my-host;

Page 259: Advanced KM Development

16.1 SNMP 251

host="myhost";2 snmp trap send(host."/162",

host." .1.3.6.1.4.1.1031 6 1 1",4 ".1.3.6.1.4.1.1031.1 string test",

".1.3.6.1.4.1.1031.2 string test 2",6 ".1.3.6.1.4.1.1031.3 string test 3",

".1.3.6.1.4.1.1031.4 string test 4"));

Listing 16.1: Simple SNMP traps in PSL tabsize

16.1.3 SNMP Trap sending

An example PSL script that can be used as a recovery action to sendSNMP traps is shown below. Note the use of “localhost” as the trapdestination.

# Get details about context2 param name = get("name");

inst name = get("../name");4 app name= get("../../name);

hostname = get("/hostname")6 platform = get("/appType");

param value=get("value");8

alarm min= get("alarmMin");10 alarm max = get("alarmMax");

status = get("status");12

param value= int(param value);14 ip address = get("/ipAddress");

bmc enterprise id = ".1.3.6.1.4.1.1031";16

targethost = "127.0.0.1";18 current time = date();

message format = "RECOVERY_TRAP %s %s %s ".20 "Host= %s IP=%s PLATFORM=%s VALUE=%s ".

"STATE=%s MIN=%s MAX=%s TIME=%s";22 msg = sprintf(message format, param name, inst name,

app name, hostname, ipAddress, platform,

Page 260: Advanced KM Development

252 PATROL and SNMP

24 param value, status, alarm min, alarm max, current time);

26 trap origin = ipAddress . " ". bmc enterprise id . " 6 255 1000";trap text = ".1.2.3.4.5 string " . msg;

28

ret = snmp trap send(targethost, trap origin, trap text);

Listing 16.2: Another SNMP trap script tabsize

16.2 SNMP Pitfalls

16.2.1 support for SNMPv2

The SNMP implementation in PATROL is only for v1. Since the SN-MPv2 protocol is mostly backward compatible with v1 the PATROLagent is able to talk to v2 agent. However, SNMP V2 introduces somenew data types. A KM written to use these datatypes would not work.Also when you receive traps from an SNMPv2 agent, it’s important toknow that ”SNMPv2 Specific datatypes” will not be understood by thePATROL agent.

new datatypes introduced in SNMPv2 :

• Unsigned32

• Counter64

If you hit one of these datatypes, you will probably not see the result,because the agent can’t decode the message properly.

Besides that SNMPv2 introduced a ”bulk” get operation. The agentwill not respond to such requests.

Page 261: Advanced KM Development

Appendix A

PSL Internal function

A.1 Windows NT PSL internal function

The PSL internal function on Windows NT accepts only 1 argument.This argument is a string command that is specific to Windows NTagent. A call to PSL internal therefore looks like:

ret = internal(cmd);

The command consists of an initial sub-command keyword followedby sub-arguments that are separated by a space. The arguments can bequoted with double quote characters if they include spaces themselves.Single quote characters are not permitted and double quotes must beused (which requires backslash escapes).

The list of sub-commands for the PSL internal command on Win-dows NT is:

• KillProcess -pid <id> — Kill an operating system process withprocess id as the 3rd argument.

• CalcPerformanceValue <counter0> <counter1> — Calculate per-formance value on the basis of two counters.

• GetPerformanceValue * | <object> [<instance>|* [<counter>|* ] ]— Get a performance value or many values.

• PerfObjectExists <object> — Determine if a performance counterexists.

• DiskPerfEnabled — Determine if disk performance data is en-abled. By default this is not enabled on Windows NT.

253

Page 262: Advanced KM Development

254 PSL Internal function

• GetRegistryValue <name> [<identifier>] — Get a value from theregistry. Examines only those values in the HKEY LOCAL MACHINEhive.

• GetRegistrySubkeys <name> — Get a list of subkeys in a registryentry. Examines only those values in the HKEY LOCAL MACHINEhive.

• GetUserRegszKeyValue <key> <subkey> —Get string value fromuser registry key.

• SetUserRegszKeyValue <key> <subkey> <value> — Set stringvalue for user registry key.

A.1.1 NT GetRegistryValue

The GetRegistryValue command for PSL internal allows access to leafnode registry values. There are two possible arguments: the registryentry variable name, and a sub-identifier for the line within that data.Both arguments are space-separated from the command as the first ar-gument to PSL internal. Here are some dummy examples to show theargument formatting:

ret = internal("GetRegistryValue Entry");ret = internal("GetRegistryValue Entry Identifier");

The first argument must be specified via its full path. The startpointof the path is HKEY LOCAL MACHINE as the root of the tree. Back-slash characters are used to specify subkey hierarchies. This backslashcharacter must itself be escaped in PSL code. For example, here is asimple call to get a particular registry value :

ret = internal("GetRegistryValue HARDWARE\\OWNERMAP");

The return value for this command on my box is:

PCI_0_5=REG_SZ=\Device\Video0

This shows the return string format of three columns. The first isthe name, the second is the type, and the third is the value. In this case,the type is REG SZ, which is a zero-byte-terminated string.

Backslashes need to appear in pairs due to the lexical tokenizationof PSL, as in most languages. To use initial backslashes would alsobe incorrect. The case of the characters used for the names of registryentries is also important. The following are incorrect examples.

Page 263: Advanced KM Development

A.1 Windows NT PSL internal function 255

# Following lines all wrongret = internal("GetRegistryValue \\HARDWARE\\OWNERMAP");ret = internal("GetRegistryValue HARDWARE\\OWNERMAP");ret = internal("GetRegistryValue hardware\\ownermap");

Another problematic issue is whitespace in registry value names. Anexample is to access the PATROL registry entry. The obvious attemptfails:

x = internal("GetRegistryValue SOFTWARE\\BMC Software\\Patrol");

The reason this fails is that there is a space in one of the names. Forspaces in names, there must be explicit quoting around the registry keyname. The solution is simply:

x = internal("GetRegistryValue \"SOFTWARE\\BMC Software\\Patrol\"");

The returned value from this is:

PORT=REG_SZ=1987

This shows a port number of 1987 specified for PATROL in the reg-istry.

The second argument to GetRegistryValue is a sub-identifier thatlimits the return code. Without a second argument, GetRegistryValuewill return a newline-separated list of 3 column output. The exampleabove has only one line, the PORT value. This gives rise to code suchas the following where the lines are grep’d out of the return values thatcontain multiple lines.

var = "\"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\"";ret = internal("GetRegistryValue ".var);build number = ntharg(grep("ˆCurrentBuildNumber", ret), 3, "=", "");os version = ntharg(grep("ˆCurrentVersion", ret), 3, "=", "");

However, another way is to use the 2nd argument to GetRegistry-Value. These code examples could be rewritten as two consecutive reg-istry entries. The 2nd argument serves to limit the return value to onlythat line that applies. Although this is not a good example, since that isprobably less efficient, the following code is equivalent.

var = "\"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\"";ret = internal("GetRegistryValue " . var . " CurrentBuildNumber");build number = ntharg(ret, 3, "=", "");ret = internal("GetRegistryValue " . var . " CurrentVersion");os version = ntharg(ret, 3, "=", "");

Page 264: Advanced KM Development

256 PSL Internal function

The error handling of the GetRegistryValue function is similar toall the commands for the NT internal function. If the wrong numberof sub-arguments is given to the command, a PSL runtime error will begenerated to the system output window, errno will be set, and the emptystring is returned by internal. Other errors such as a non-existent reg-istry entry have similar error handling behavior.

A.1.2 NT GetRegistrySubkeys

The GetRegistrySubkeys command in the internal function returns alist of sub-keys of a particular key in the registry. The only argument isthe name of the registry value which is placed after a space in the stringfor the first argument. The parent is assumed to already be implicitly”HKEY LOCAL MACHINE” and paths relative to this node are speci-fied via backslash sequences. Some examples of getting a list of subkeysare:

ret = internal("GetRegistrySubkeys SYSTEM");

The return value is a newline-separated list of subkey names. The out-put of this command could look like:

ControlSet001ControlSet002ControlSet003DISKSelectSetupCloneCurrentControlSetControlSet001ControlSet002ControlSet003DISKSelectSetupCloneCurrentControlSet

As for GetRegistryValue, any keys containing space characters need tobe wrapped in quotes. The example for accessing the subkeys of BMCSoftware becomes:

Page 265: Advanced KM Development

A.1 Windows NT PSL internal function 257

x = internal("GetRegistrySubkeys \"SOFTWARE\\BMC Software\"");

The return value from an execution of this command could look like;

CommonKMPatrolPATROL PathfinderPATROLWATCH

The error handling of GetRegistrySubkeys is similar to GetRegistry-Value. If the specified key is not a sub-key with real children, the inter-nal function returns the empty string, sets errno, and may write a PSLruntime error to the system output window (depending on the value ofthe special PslDebug variable).

A.1.3 NT PerfObjectExists

The PerfObjectExists command detects whether a performance counterobject is available. The return value is ”0” or ”1” depending on whetherthe performance object exists. The return value is the empty string ifthere is a missing argument or too many arguments. The argument toPerfObjectExists can be surrounded in double quotes, which allows aname containing spaces. Here is an example of determining whetherthe CPU processor has its performance monitoring enabled, which isthe default :

ret = internal("PerfObjectExists Processor");

This code will typically return ”1” for success.

A.1.4 NT DiskPerfEnabled

The DiskPerfEnabled command to PSL internal checks if disk perfor-mance data collection is enabled. By default this collection is not en-abled on Windows NT. The return value of this command is either ”0\n”or ”1\n”. The newline that is appended to the result makes it slightlytricky to test the return value, because the newline must be strippedout. A typical use of DiskPerfEnabled looks like:

ret = internal("DiskPerfEnabled");ret = trim(ret, "\n");if ( ret)

Page 266: Advanced KM Development

258 PSL Internal function

{# Disk performance collection data is available

}

The absence of the trim function will cause the ’if ’ statement tosucceed even when the data is not really available. This is a specialcase of the pitfall involving the string-like representation of numbers inPSL. The newline character causes PSL to perform a string not-equal-to-empty-string test instead of a numeric test for non-zero.

A.1.5 NT GetPerformanceValue

The GetPerformanceValue command in PSL internal gets one or manyvalues from the NT performance database. The first possible usage ofGetPerformanceValue is without any of the arguments. This returns alist of performance objects that are available. The sample code is:

perf objs = internal("GetPerformanceValue");

This returns a newline-separated list of performance object names. Thiscan be used to determine which performance counters are being col-lected by the operating system with its current configuration.

However, there can also be arguments to limit the search for perfor-mance objects, and return the values of the performance counters. Thesyntax of the command is basically:

ret = internal("GetPerformanceValue <object> <instance> <counter>");

Any three of these arguments can be the star character (*) to indicateany one be considered. Therefore, an example of accessing all the per-formance objects of the SYSTEM object is:

ret = internal("GetPerformanceValue System * *");

When used with normal arguments, the return value for GetPerfor-manceValue is a newline-separated list of counter information. Eachline has a complicated format. The first field is the full name of the per-formance counter, including any whitespace that is part of the name.This is followed by an ”=” character, and the second part of the counterinformation is a sequence of strange numbers. For example, the outputfrom the above call is:

File Read Operations/sec=10410400,368717,,177:8344ace0File Write Operations/sec=10410400,9164,,177:8344ace0

Page 267: Advanced KM Development

A.1 Windows NT PSL internal function 259

File Control Operations/sec=10410400,5903810,,177:8344ace0File Read Bytes/sec=10410500,0:2f38a2a,,177:8344ace0File Write Bytes/sec=10410500,0:beca83,,177:8344ace0File Control Bytes/sec=10410500,0:8db2ad51,,177:8344ace0Context Switches/sec=10410400,15409294,,177:8344ace0System Calls/sec=10410400,56834562,,177:8344ace0% Total Processor Time=21510500,96:a08f7c20,,177:8344ace0% Total User Time=20510500,d3:23be39e0,,177:8344ace0% Total Privileged Time=20510500,d:bef97130,,177:8344ace0Total Interrupts/sec=10410400,33046571,,177:8344ace0File Data Operations/sec=10410400,377881,,177:8344ace0System Up Time=30240500,0:2756f,,177:8344ace0Processor Queue Length=10000,1,,177:8344ace0Alignment Fixups/sec=10410400,0,,177:8344ace0Exception Dispatches/sec=10410400,1211,,177:8344ace0Floating Emulations/sec=10410400,0,,177:8344ace0% Total DPC Time=20510500,4:839e9a60,,177:8344ace0% Total Interrupt Time=20510500,1:5bdd3920,,177:8344ace0Total DPCs Queued/sec=10410400,16075099,,177:8344ace0Total DPC Rate=10000,0,,177:8344ace0Total DPC Bypasses/sec=10410400,0,,177:8344ace0Total APC Bypasses/sec=10410400,1988041,,177:8344ace0% Registry Quota In Use=20020400,5946735,8388608,177:8344ace0

An another example, consider the following code:

objects = internal("GetPerformanceValue Objects * *");print(objects);

The output from this sequence is a list of counters, with the name, an= sign, and then a sequence of numbers in a complex comma-separatedfield.

Processes=10000,28,,177:836469e0Threads=10000,148,,177:836469e0Events=10000,362,,177:836469e0Semaphores=10000,126,,177:836469e0Mutexes=10000,65,,177:836469e0Sections=10000,201,,177:836469e0

Note that the second and third arguments cannot be omitted whenattempting to get all the objects. The following example code snippet isincorrect:

Page 268: Advanced KM Development

260 PSL Internal function

ret = internal("GetPerformanceValue System"); # WRONGret = internal("GetPerformanceValue System *")); # WRONGret = internal("GetPerformanceValue System * *")); # CORRECT

The instance and counter (2nd and 3rd) arguments to GetPerformance-Value can be used to return more specific data. An example is:

sys = "GetPerformanceValue System * ";ret = internal(sys."\"Floating Emulations/sec\"");

Note that the double quotes a necessary because of the space in thename. The following code would be erroneous because the spaces in thename are not taken into account:

sys = "GetPerformanceValue System * ";ret = internal(sys."Floating Emulations/sec"));

The processing of performance data values is typically completed by theuse of the CalcPerformanceValue command also in PSL internal. How-ever, it can also be performed manually via PSL as is now discussed.

A.1.6 NT GetPerformanceValue Counter Format Details

The detailed specification of the returned format for each counter fromGetPerformanceValue is related to the return from the HKEY PERF DATAWIN32 APIs. The general syntax for the fields returned is:

<Counter Name> "=" <Counter Type> ","<Counter field 1> "," <Counter field 2> ","<Counter field N> "," <64-bit timestamp>

Here is some partial output of a GetPerformanceValue call. Thisshows some of the features of the return value format:

Total DPC Rate=10000,0,,177:8344ace0Total DPC Bypasses/sec=10410400,0,,177:8344ace0Total APC Bypasses/sec=10410400,1988041,,177:8344ace0% Registry Quota In Use=20020400,5946735,8388608,177:8344ace0

The number of fields can vary according to the counter returned.However, four fields are always represented at a minimum even if one ormore is empty. Field usage is based on the actual performance counterbeing queried, which varies. Counter fields are either DWORD or 64-bit

Page 269: Advanced KM Development

A.1 Windows NT PSL internal function 261

INTEGER. The Performance Counters are documented in the WindowsNT Resource Kit manuals.

The return value of some numbers typically has a colon (:) characterin some fields. These fields are 64-bit integers or 64-bit timestamps. Be-cause the 64-bit entity is actually two 32-bit parts, the colon is used todenote that. This basically serves as an aid in scanning and storage ofthe field as two 32-bit parts. The first field containing the counter typeshould always be decimal. The 64-bit integers and 64-bit timestampsare in hexadecimal, which poses some problems for PSL processing, al-though a solution is shown in a section below.

A.1.7 NT CalcPerformanceValue

The CalcPerformanceValue is typically used to decode the format ofcounter values returned by GetPerformanceValue. The main purposeis to compute deltas from consecutive data points returned by GetPer-formanceValue. The format of the CalcPerformanceValue command is:

internal("CalcPerformanceValue <counter1> <counter2>");

In both cases, the counters are in the format as returned by the secondhalf of the GetPerformanceValue command in PSL internal. This is allthe textual numeric data after the counter name and the ”=” characterin the return value.

Here is a simple example of a counter value calculation comparedwith itself. The result is zero because there is no change in the counter.

counter = "10410400,368717,,177:8344ace0";ret = internal("CalcPerformanceValue " . counter . " " . counter);

The return value here from PSL internal is 0.000000. Note that thespaces are necessary to separate the arguments in the command string.

Note that using the counter name as an argument to CalcPerfor-manceValue causes failure. The return will be the empty string, and aPSL runtime warning message may be generated.

counter = "File Read Operations/sec="."10410400,368717,,177:8344ace0";

ret = internal("CalcPerformanceValue " . counter . " " . counter);

This means that the results of GetPerformanceValue need to be strippedof the first counter name field. This is typically done via nthargf().

# Get new value

Page 270: Advanced KM Development

262 PSL Internal function

cur token = nthargf(counter, "2-", "=", "");# Get stored old valueprev token = get(base."/prev" . param name);val = internal("CalcPerformanceValue ".

prev token . " ". cur token );

A.1.8 NT GetUserRegszKeyValue

This function is aimed at getting the value of user-defined registry en-tries with a string type. As a caveat, this command appears to havesome bugs, even in the recent 3.2 NT agent. The absence of any ar-guments, or supplying arguments that are not valid seem to make theagent crash in 3.2, and possibly on earlier agents. This function maywell be best avoided until a post-3.2 release fixes the problem. Even so,reliance on these functions will impose a compatibility problem for 3.2and earlier agents.

A.2 Compatibility of NT Internal Commands

All of the internal commands for the PSL internal function have beensupported since version 3.0 of the Windows NT agent. They are alsosupported on all current Windows NT versions that the agent supports,such as 3.51 and 4.0. At this time of writing (Aug 97), the NT 5.0 agentis not supported, and the status of the PSL internal function for the NT5.0 agent is unclear.

A.3 UNIX PSL internal function

The only internal command on UNIX is ”diskInfo”. The diskInfo com-mand retrieves information similar to the UNIX “df” command, anddoes so by direct access of low-level data files generated by the kernel.The diskInfo command can be used alone, or with an optional secondfilename argument.

internal("diskInfo");internal("diskInfo", filename);

The diskInfo command will do a ”discovery” of disks currently mountedand populate an internal-symbol table. This internal table will containonly those file-systems that are currently mounted. Therefore, if you

Page 271: Advanced KM Development

A.3 UNIX PSL internal function 263

call this command again, any filesystems that are no longer mountedwill be removed from the internal table and newly mounted filesystemswill be added. A string will be returned that represents the ”top-level”node in this symbol-table; this is currently “/internal/df”. You can thenuse this string to determine what filesystems were found. The followingcode prints the list of filesystems discovered:

TopLevel = internal("diskInfo");print(get vars(TopLevel, "nodes"));

The get vars() call will print the names of the filesystems with the “/”character changed to “-”.

For each filesystem, the function stores the following computed vari-ables in the agent table space. These are all available via a PSL get callusing the symbolic name.

Symbolic Name Computed ValuemountPt Actual mount point pathnamemountDev Mounted from where; which device namemountOpt Mount optionsfsType Filesystem typefreeKB Free kilobytestotKB Total kilobytesavailKB Available kilobytestotInodes Total inodesfreeInodes Number of free inodes

For example, after executing PSL internal, the following PSL getcommand will return the number of free kilobytes in the “root” filesys-tem:

print(get("/internal/df/root/freeKB"));

If any of the numeric elements is ”-1”, this means the value is un-available. This possibility applies to the freeInodes, totInodes, availKB,totKB, and freeKB statistical values. The optional second argument toPSL internal is the name of a file. If provided, the string returned byPSL internal will the name of filesystem instance that contains the re-quested file. This call will also do a ”discovery” of other filesystems, aswas done above without the second filename argument, and thereforethe only difference in functionality is the string returned.

fsinst = internal("diskInfo", "/some/path");print(get(fsinst . "freeKB");

Page 272: Advanced KM Development

264 PSL Internal function

Note that the path returned when PSL internal is called with a secondargument is the ”real” path without the “/” characters changed to the “-“character. Not all UNIX agent platforms support diskInfo, although itis currently available on Solaris, HP-UX, AIX, Digital UNIX, NCR, DG-UX, Motorola, SGI, Sequent, and SunOS. However, it is currently notsupported on SCO, Ultrix, Unixware, and Unisys. The “diskInfo” com-mand is not supported on any non-UNIX platforms such as WindowsNT, OS/2, VMS or MVS.

The PSL internal function on UNIX will return the empty stringupon error, or on an unsupported platform. The PSL errno special vari-able is not set by the internal function.

A.4 VMS internal function

The following commands are allowed for PSL internal on the VMS agent:

GetProcessCache [procid]GetProcessInfo [PROC_NAME | PROC_PID] [NAME | PID]GetQueueInfo [Queuename [...]]GetSystemInfo [info [...]]

All of these commands are only available on the VMS agent. Theyare not available on the UNIX, OS/2, MVS or Windows NT agents.These commands will return a failure from PSL internal on those plat-forms.

A.4.1 VMS GetProcessCache

The format of the GetProcessCache command in PSL internal for VMSonly is:

GetProcessCache [procid]

This function gets the information used for the process cache. Ittakes as a parameter the process id of a process to obtain the cacheinformation for. For example, the numeric id of a known process can befound via a call such as:

procnum = 0; # Whatever id is relevant; usually a computed variableret = internal("GetProcessCache " . procnum);

Page 273: Advanced KM Development

A.4 VMS internal function 265

A value of * for the procid argument returns the information for allprocesses on the system, with an output format of one process per line.This command example looks like:

ret = internal("GetProcessCache *"); # get all processes

A.4.2 VMS GetProcessInfo

The syntax of the GetProcessInfo command to PSL internal on VMS is:

GetProcessInfo [PROC_NAME | PROC_PID] [NAME | PID]

This function takes as an argument the keyword PROC NAME or PROC PIDfollowed by a process name or pid. It returns the process id, state, CPU-time, buffered I/O, direct I/O, and page faults. The return items are oneper line in the following order:

PROCESS IDSTATECPU TIMEBUFFERED IODIRECT IOPAGEFAULTS

A.4.3 VMS GetQueueInfo

The syntax of this command to PSL internal on VMS is:

GetQueueInfo [Queuename [...]]

This function gets information on system queues. As parameters ittakes a queue-name (wildcards are valid) and a list of items to return.The items can be any combination of the following:

QUEUE_NAMEQUEUE_STATEQUEUE_TYPEQUEUE_FORM_NAME_DEFQUEUE_FORM_STOCK_DEFQUEUE_FORM_NAMEQUEUE_FORM_STOCKQUEUE_DEVICE_NAME

Page 274: Advanced KM Development

266 PSL Internal function

QUEUE_SYMBIONTQUEUE_PRIORITYQUEUE_PROTECTIONQUEUE_JOB_COUNT_EXECQUEUE_JOB_COUNT_PENDQUEUE_JOB_COUNT_HOLDQUEUE_JOB_LIMITQUEUE_OWNER_UIC

The result is a string, with one line per queue. Each item will be sepa-rated by ’;’. If you do not specify any items, the result will contain:

QUEUE_NAMEQUEUE_STATEQUEUE_TYPEQUEUE_FORM_NAME_DEFQUEUE_FORM_STOCK_DEFQUEUE_DEVICE_NAMEQUEUE_SYMBIONTQUEUE_PRIORITYQUEUE_PROTECTIONQUEUE_JOB_COUNT_EXECQUEUE_JOB_COUNT_PENDQUEUE_JOB_COUNT_HOLDQUEUE_JOB_LIMITQUEUE_OWNER_UIC

It is recommended that you not obtain information about multiple queuesas this may impact the performance of the agent.

A.4.4 VMS GetSystemInfo

The syntax of this command to PSL internal on VMS is:

GetSystemInfo [info [...]]

This function will return information about the system. It can obtainthe following information:

ARCH_NAMEBOOTTIMENODENAME

Page 275: Advanced KM Development

A.4 VMS internal function 267

NODE_NUMBERNODE_AREAVERSIONHW_NAMEAVAILCPU_CNTCLUSTER_MEMBERARCH_NAMECLUSTER_EVOTESCLUSTER_NODESCLUSTER_VOTESCONTIG_GBLPAGESFREE_GBLPAGESFREE_GBLSECTSPAGEFILE_FREEPAGEFILE_PAGESWAPFILE_FREESWAPFILE_PAGE

Unlike the Queue function you must specify at least one item and eachitem is returned on a separate line.

Page 276: Advanced KM Development

268 PSL Internal function

Page 277: Advanced KM Development

Appendix B

(Micro-)Optimizing yourcode

B.1 Introduction

Usually, something that keeps most developers busy is trying to opti-mize code. It does make one feel more proud of his work after havingbeen able to improve performance. However, sometimes the optimiza-tion turns into an obsession and more and more into micro optimizationwhere you are not really achieving a lot more by making changes to thecode that seems to work fine.

Instead of just writing about optimization in general, I thought itwould be nicer to see how optimization can happen in practice.

The problem that we are trying to solve is very simple : ”Find thefastest way to get the last word on a line. We are just interested in thelast word.”.

If you want to look for the last word in a line and you are not inter-ested in the number of words you would type something like this in awkon UNIX

echo $LINE | awk ’{print $NF}’

Although this solution sounds simple, it would require multiple pro-cesses in UNIX and it is not really platform independent. Anyway, sincethis is a book about PATROL, you can imagine that we will be lookingfor the best possible solution in PSL.

269

Page 278: Advanced KM Development

270 (Micro-)Optimizing your code

In PSL, straight forward coding would produce this :

# Don’t know how much words in a line, but need last wordnumber words = 0;foreach word w (myline){

number words++;}# Now get the wordlastword = ntharg (myline, number words);

B.2 First Optimization

When we look closely at this little PSL program, we can easily see thatthere is a lot of useless code in the program. The reason why we arecounting the number of words is because we want to use ntharg to getthe last work from the line.

If we look carefully, we see that all that counting is not really nec-essary, because what do you think the value of ”w” will be at the end ofthe program?Exactly : The last word !

So our first example can be rewritten as :

foreach word lastword (myline) {}

This will result in an empty loop. Each time this (empty) loop exe-cutes the variable lastword will be assigned the value of the next wordin myline. At the end of the statement, the foreach will exit, but last-word will still have the value of the last word of the line

Page 279: Advanced KM Development

B.3 Prevent looping 271

B.3 Prevent looping

We still have a loop, and we know performance might be even betterwithout loops. So how can we rewrite the code so we don’t have loopinganymore ?

The original code was . . .

# Don’t know how much words in a line, but need last wordnumber words = 0;foreach word w (myline){

number words++;}# Now get the wordlastword = ntharg (myline, number words);

In our first optimization step we kept the loop, but just removedeverything we didn’t need. What we will try to do now, is rewrite thecode, but without loops. This means : find another way of getting thenumber of words without a loop.

We came up with the following solution :

wordlist = ntharg(myline, "1-");num words = lines(wordlist);lastword = ntharg(myline, num words);

If we compare this with our first optimized version, we replaced onesingle line of code with three lines of code. but without any loops.

• The fist statement will break the line in a list of words.

• The second statement will count the number of words.

• The third statement will get the actual word.

If we profile this code, we see that it works faster than the original,but performance is practically the same as our first optimization.

Page 280: Advanced KM Development

272 (Micro-)Optimizing your code

B.4 Micro Optimization

We have already optimized the basic code, and probably this is wherewe should stop, but the purpose of this discussion is to go as deep as wepossibly could.

It was clear that our foreach loop wouldn’t bring us further optimiza-tion. Since we know that looping is quite expensive (although we onlyused one PSL statement in our solution and that was foreach)

The second example (as fast as the empty foreach()) however hadthree statements, maybe we can optimize something there. Let’s take alook at our code again.

wordlist = ntharg(myline, "1-");num words = lines(wordlist);lastword = ntharg(myline, num words);

Line two and three can be combined in a single PSL function : tail ().Therefore we found our real performance winner

wordlist = ntharg(myline, "1-");lastword = tail (wordlist,1);

When I talk about performance gain between optimized 1,2 or 3, itis more in 1/10 seconds than in real seconds, but the difference betweenthe original and 3 will speed processing with 20-50

B.5 Another problem

Now let’s try a variation of the problem :”Find the last word in a textblock (that means a block with newlines in it)”

It should be obvious that even our best optimized example will notreally be good enough for this problem.

wordlist = ntharg(myline, "1-");lastword = tail (wordlist,1);

On a full text block, this piece of code will produce the correct re-sult, but not with the expected performance, because now our completemulti-line text is changed into a list.

Page 281: Advanced KM Development

B.6 Aren’t One-liners even faster ? 273

Of course a simple modification will solve the problem

last line = tail(mytext,1);last word list = ntharg(last line, "1-")last word = tail ( last word list ,1);

Now if you want to offer this as a function in a library that morethan just you will use, you could ask yourself which of the optimizedversions you should use.

The answer is very simple : make sure to implement the last exam-ple, that will perform best for the worst case scenario and reasonablygood for the best case scenario.

Indeed, the end user of your library doesn’t know how your functionwill behave with a certain input (and he shouldn’t care). The enduserwill expect a reasonable result, no matter what the input will be.

Just as a comparison :

• In cases where you don’t have a newline in the input (so only asingle line as input), the result will be a about 2mean is probablymeasured in hundreds of a second.

• In the cases where you have multi-lines (for example 1000 lines),you will see at least a 7000

So don’t worry about the tail, if you don’t know what your input is.

B.6 Aren’t One-liners even faster ?

Some people think that writing one-liners must definitely be faster thanmulti-line code. Let’s compare the two

last line = tail(mytext,1);last word list = ntharg(last line, "1-");last word = tail ( last word list ,1);

and

tail(ntharg(tail(mytext,1),"1-"),1);

Page 282: Advanced KM Development

274 (Micro-)Optimizing your code

If you want to see what is really happening, just run both pieces ofcode through the standalone psl compiler psl -q and you will get :

last line = tail (...)last word list = ntharg (...)last word = tail (...)

and

@temp 1 = tail (...)@temp 2 = ntharg (...)@temp 3 = tail (...)

At a first glance, you will say that this is the same, but if you lookcarefully there is more to say than that.

For the one-liner, the PATROL agent has assigned unnames localvariables himself. These are temporary variables that he needs in orderto pass arguments.

These unnamed variables are @temp 1, @temp 2 and @temp 3. Inthe first dump, you can see that these unnamed variables have beenreplaced with my ”named” variables.

These are : last line, last word list and last wordSo there is definitely no performance gain, but it’s even worse if you

use one-liners. If you would have liked to use the result of the (ntharg())for something else (eg. To get the first word of the last line), you wouldn’thave been able to access that data, since all @temp variables are inter-nal to the interpreter and cannot be used in PSL.

And one-liners can definitely be harder to maintain.

B.7 Don’t trust everything you copy and paste

A typical PSL developer makes extensive use of the copy/paste buttons.Sometimes that is a good thing, but very frequently the source you arecopying from might not be written in the best way.

For example the PSL reference manual is supposed to be educationalmaterial and the majority of the examples in the PSL reference manualare good examples. From time to time, you will run into an examplethat was written not suited for what you are trying to do.

You must understand that the examples are there to explain howthe function works, not to give people the fastest code of doing things.Readability is also very important in a manual that shows code samples.You also have to keep the examples simple. From what we learned so far

Page 283: Advanced KM Development

B.7 Don’t trust everything you copy and paste 275

is that optimization doesn’t necessarily means complex, but sometimesintroduces some complexity in the thought process.

The most important thing is : you have to think for yourself as youwrite

Just to proof that some things can be done better, I looked in the PSLmanual. On PSL manual page 4-48 you will find an example that willdisplay this :

Waveform for consine :

-1 -0.5 0 0.5 1+----+----+----+----+

0.00 | * cosine = +1.0000000.10 | * cosine = +0.9950040.20 | * cosine = +0.9800670.30 | * cosine = +0.9553360.40 | * cosine = +0.9210610.50 | * cosine = +0.8775830.60 | * cosine = +0.8253360.70 | * cosine = +0.7648420.80 | * cosine = +0.6967070.90 | * cosine = +0.6216101.00 | * cosine = +0.5403021.10 | * cosine = +0.4535961.20 | * cosine = +0.3623581.30 | * cosine = +0.2674991.40 |* cosine = +0.1699671.50 * cosine = +0.0707371.60 *| cosine = -0.0292001.70 * | cosine = -0.1288441.80 * | cosine = -0.2272021.90 * | cosine = -0.3232902.00 * | cosine = -0.4161472.10 * | cosine = -0.5048462.20 * | cosine = -0.5885012.30 * | cosine = -0.6662762.40 * | cosine = -0.7373942.50 * | cosine = -0.8011442.60 * | cosine = -0.8568892.70 * | cosine = -0.904072

Page 284: Advanced KM Development

276 (Micro-)Optimizing your code

2.80 * | cosine = -0.9422222.90 * | cosine = -0.9709583.00 * | cosine = -0.9899923.10 * | cosine = -0.9991353.20 * | cosine = -0.998295

The developer who wrote this, obviously didn’t think of all the func-tions you have at your disposal in PATROL, but probably wanted tomake to code readable.

This is his listing :

function main(){

print("Cosine Waveform:\n\n");print(" -1 -0.5 0 0.5 1\n");print(" +----+----+----+----+\n");i = 0.0;while (i <= 3.2){

printf("%4.2f ",i);cosine = cos(i );plot = int(10 ∗ cosine) + 10;if ( plot < 10){

before = "";j = 1;while (j <= plot){

before = before . " ";j++;

}after = "";j = plot;while (j < 9){

after = after . " ";j++;

}print(before,"*",after,"|");printf(" cosine = %+8.6f\n",cosine);

}

Page 285: Advanced KM Development

B.7 Don’t trust everything you copy and paste 277

elsif ( plot == 10){

print(" * ");printf(" cosine = %+8.6f\n",cosine);

}else{

print(" |");before = "";j = 11;while (j < plot){

before = before . " ";j++;

}print(before,"*");after = "";j = plot + 1;while (j <= 22){

after = after . " ";j++;

}print(after);printf("cosine = %+8.6f\n",cosine);

}i = i + 0.1;

}}

The logic of this program is to build each line character by character.Personally, I don’t think the program is very readable. If you under-

stand what he does, it is OK, but if you have to change something, youmust be careful where you change what ... Also there is a lot of loopingand branching.

Page 286: Advanced KM Development

278 (Micro-)Optimizing your code

Thinking it all over, I came up with the following listing :

# Print the headerprint("Waveform for consine :\n\n".

" -1 -0.5 0 0.5 1\n"." +----+----+----+----+\n");

# We know each line will at least print this character string# plus an asterix somewherewhole line=" | ";

# Loop over the degreesfor ( i=0;i<=3.2;i+=0.1){

# Find the cosine valueval=cos(i);# See where on the line of 20 long the asterix should be putplot=int(10∗val)+10;# Break the line in two and later rebuild the line# using a printfpart one=substr(whole line,1,plot);part two=substr(whole line,plot+2,20); # 20 is maxlength of lineprintf("%4.2f %s*%s cosine = %+8.6f\n",

i ,part one,part two,val);}

The logic of this program is to take a line and put the ”*” where itbelongs... We just break the line apart where needed.

This increases the speed incredibly.... (x2) and it (to my understand-ing) more readable code.

Another approach might have been that you took the first bit of code,and rewrote it so it looked more ”compact” (we already know this isn’tnecessarily good).

Page 287: Advanced KM Development

B.7 Don’t trust everything you copy and paste 279

Let’s take a look at what we can do when we look at the first example,but rewrote it a bit :

for ( i=print("Cosine Waveform:\n\n -1"." -0.5 0 0.5 1\n "."+----+----+----+----+\n");i<=3.2;i+=0.1) {printf("%4.2f %s cosine = %+8.6f\n",i,(plot = int(10 ∗ (cosine = cos(i )))) < 0 ?sprintf(sprintf("%%%ic%%%ic| ",11+plot,−plot),"*","") :(( plot == 0) ? " * " : sprintf(sprintf(" |%%%ic%%%ic",plot, 11−plot),"*"," ")),cosine);}

This example IS a huge one-liner in a loop and it does the same.It uses advanced functions like nested sprintf ’s and nested ternary

operators, it also uses assignments in statements and every other thingyou wouldn’t do as a beginning programmer.

As a result, the code we produced is unreadable, unmaintainableand even not better/faster than the optimization we did.