Channel event logging (CEL) is a new system that was created to provide a more flexible means of logging the details of complex call scenarios. Instead of collapsing a call down to a single log entry, a series of events are logged for the call. This provides a more accurate picture of what has happened to the call, at the expense of a more complex log.
Each CEL record represents an event that occurred for a channel in the Asterisk system. Table 24.7, “CEL event types” lists the events that are generated by Asterisk as calls are processed.
Table 24.7. CEL event types
| CEL event type | Description | 
|---|---|
| CHAN_START | A channel has been created. | 
| CHAN_END | A channel has been destroyed. | 
| LINKEDID_END | The last channel with a given linkedidhas been destroyed. | 
| ANSWER | A channel has been answered. On a channel created for an outbound call, this event will be generated when the remote end answers. | 
| HANGUP | A channel has hung up. Generally, this event will
              be followed very shortly by a CHAN_ENDevent. The difference is that
              this event occurs as soon as a hangup request is received,
              whereasCHAN_ENDoccurs after
              Asterisk has completed post-call cleanup and all resources
              associated with that channel have been released. | 
| APP_START | A tracked application has started executing on a channel. Tracked applications are set in the main CEL configuration file, which is covered in the section called “cel.conf”. | 
| APP_END | A tracked application has stopped executing on a channel. | 
| PARK_START | A channel has been parked. | 
| PARK_END | A channel has left the parking lot. | 
| BRIDGE_START | A channel bridge has started. This event occurs
              when two channels are bridged together by an application such as Dial()orQueue(). | 
| BRIDGE_END | A channel bridge has ended. | 
| BRIDGE_UPDATE | An update to a bridge has occurred. This event will reflect if a channel’s name or other information has changed during a bridge. | 
| BLINDTRANSFER | A channel has executed a blind transfer. | 
| ATTENDEDTRANSFER | A channel has executed an attended transfer. | 
| USER_DEFINED | A user-defined channel event has occurred. These
              events are generated by using the CELGenUserEvent()application. | 
There are some more events that have been defined, but are not yet used anywhere in the Asterisk code. Presumably, some future version will generate these events in the right place. They are listed in Table 24.8, “Defined but unused CEL event types”.[172]
Table 24.8. Defined but unused CEL event types
Each CEL event contains the fields listed in Table 24.9, “CEL event fields”:
Table 24.9. CEL event fields
| Field name | Value/Example | Notes | 
|---|---|---|
| eventtype | CHAN_START | The name of the event. The list of events that may occur can be found in Table 24.7, “CEL event types”. | 
| eventtime | 2010-08-19 07:27:19 | The time that the event occurred. | 
| cidname | Julie Bryant | The caller ID name set on the channel associated with this event. | 
| cidnum | 18435551212 | The caller ID number set on the channel associated with this event. | 
| cidani | 18435551212 | The Automatic Number Identification (ANI) number set on the channel associated with this event. | 
| cidrdnis | 18435551234 | The redirecting number set on the channel associated with this event. | 
| ciddnid | 18435550987 | The dialed number set on the channel associated with this event. | 
| exten | 101 | The extension in the dialplan that is currently being executed. | 
| context | LocalSets | The context for the extension in the dialplan that is currently being executed. | 
| channame | SIP/0004F2060EB4-00000010 | The name of the channel associated with this event. | 
| appname | Dial | The name of the dialplan application currently being executed. | 
| appdata | SIP/0004F2060E55 | The arguments that were passed to the dialplan application that is currently being executed. | 
| amaflags | DOCUMENTATION | The Automatic Message Accounting (AMA) flag associated
              with this call. This may be one of the following: OMIT,BILLING,DOCUMENTATION, orUnknown. | 
| accountcode | 1234 | An account ID. This field is user-defined and is empty by default. | 
| uniqueid | 1282218999.18 | The unique ID for the channel that is associated with this event. | 
| userfield | I like waffles! | User-defined event content. | 
| linkedid | 1282218999.18 | The per-call ID. This ID helps tie together multiple
              events from multiple channels that are all a part of the same
              logical call. The ID comes from the uniqueidof the first channel in the
              call. | 
| peer | SIP/0004F2060E55-00000020 | The name of the channel bridged to the channel identified
              by channame. | 
Some of the contents of a CEL event are
      user-defined. For example, the userfield is user-defined and will be empty by
      default. To set it to something, use the CHANNEL() dialplan function. Here is an
      example of setting the userfield for
      a channel:
exten => 101,1,Set(CHANNEL(userfield)=I like waffles!)
The CEL system includes a single dialplan application that
      lives in the app_celgenuserevent.so
      module. This application is used to generate custom user-defined events
      of the type EV_USER_EVENT. A
      practical example of using this would be for logging a caller’s choices
      in a menu:
exten => 7,1,CELGenUserEvent(MENU_CHOICE,Caller chose option 7)
For full current details on the syntax of
      the CELGenUserEvent() application,
      use the built-in documentation from the Asterisk CLI:
*CLI> core show application CELGenUserEventThe CEL system has a single configuration file, /etc/asterisk/cel.conf. All options set here
      affect CEL processing, regardless of which logging backend modules are
      in use. Table 24.10, “cel.conf [general] section options” shows the options that exist
      in this file. All options should be set in the [general] section of the configuration file.
Table 24.10. cel.conf [general] section options
As with the CDR system, there are a number of backend
      modules available for logging CEL events. In fact, all of the CEL
      backend modules were derived from CDR modules, so their configuration is
      very similar. In addition to the configuration options for cel.conf, which were described in the
      previous section, these modules require configuration to make them
      operate.
The cel_odbc.so
        module provides the ability to log CEL events to a database using
        ODBC. This module is not quite as adaptive as the CDR adaptive ODBC
        backend. For CEL events, there are no custom variables. However, this
        module will still adapt to the structure of the database, in that it
        will log the fields of CEL events for which there are corresponding
        columns and will not produce an error if there is not a column for
        every field. The configuration for this module goes in /etc/asterisk/cel_odbc.conf.
Multiple tables may be configured in
        the cel_odbc configuration file.
        Each goes into its own configuration section. The name of the section
        can be anything; the module does not use it. Here is an example of a
        simple table configuration:
[mytable] connection = asterisk table = asterisk_cel
The cel_odbc module will use the following
        columns, if they exist (see the table following this list for a set of
        mappings between event types and their integer value that will be
        inserted into the database):
Table 24.11, “Event type to integer value mappings for the eventtype
          column”
        shows the mapping between event types and their integer values that
        will be inserted into the eventtype
        column of the database.
Table 24.11. Event type to integer value mappings for the eventtype column
| Event type | Integer value | 
|---|---|
| CHANNEL_START | 1 | 
| CHANNEL_END | 2 | 
| HANGUP | 3 | 
| ANSWER | 4 | 
| APP_START | 5 | 
| APP_END | 6 | 
| BRIDGE_START | 7 | 
| BRIDGE_END | 8 | 
| CONF_START | 9 | 
| CONF_END | 10 | 
| PARK_START | 11 | 
| PARK_END | 12 | 
| BLINDTRANSFER | 13 | 
| ATTENDEDTRANSFER | 14 | 
| TRANSFER | 15 | 
| HOOKFLASH | 16 | 
| 3WAY_START | 17 | 
| 3WAY_END | 18 | 
| CONF_ENTER | 19 | 
| CONF_EXIT | 20 | 
| USER_DEFINED | 21 | 
| LINKEDID_END | 22 | 
| BRIDGE_UPDATE | 23 | 
| PICKUP | 24 | 
| FORWARD | 25 | 
Table 24.12, “cel_odbc.conf table configuration”
        shows the options that can be specified in a table configuration
        section in the cel_odbc.conf
        file.
Table 24.12. cel_odbc.conf table configuration
In addition to the key/value pair
        fields that are shown in the previous table, cel_odbc.conf allows for a few other
        configuration items. The first is a column alias. Normally, CEL fields
        are logged to columns of the same name. An alias allows the variable name to be mapped
        to a column with a different name. The syntax is:
alias<CEL field>=><column name>
Here is an example column mapping using
        the alias option:
alias exten => extension
It is also possible to specify a content filter. This allows you to specify criteria that must match for records to be inserted into the table. The syntax is:
filter<CEL field>=><content>
Here is an example content filter:
filter appname => Dial
Finally, cel_odbc.conf allows static content to be
        specified for a column. This can be useful when used along with a set
        of filters. This static content can
        help differentiate records that were inserted into the same table by
        different configuration sections. The syntax for static content
        is:
static<"Static Content Goes Here">=><column name>
Here is an example of specifying static content to be inserted with a CEL event:
static "My Content" => my_identifier
This CEL backend allows for custom formatting of CEL
        events in a log file. It is most commonly used for customized CSV
        output. The configuration file used for this module is /etc/asterisk/cel_custom.conf. A single
        section called [mappings] should
        exist in this file. This section contains mappings between filenames
        and the custom templates for CEL events. The templates are specified
        using Asterisk dialplan functions and a few special CEL
        variables.
The following example shows a sample
        configuration for cel_custom that
        enables a single CEL log file, Master.csv. This file will be created as
        /var/log/asterisk/cel-custom/Master.csv.
        The template that has been defined uses the CHANNEL(), CALLERID(), and CSV_QUOTE() dialplan functions. The CSV_QUOTE() function ensures that the values
        are properly escaped for the CSV file format. This example also
        references some special CEL variables, which are listed in Table 24.13, “CEL variables available for use in [mappings]”.
Table 24.13. CEL variables available for use in [mappings]
Here is the example /etc/asterisk/cel_custom.conf file:
[mappings]
Master.csv => ${CSV_QUOTE(${eventtype})},${CSV_QUOTE(${eventtime})},
    ${CSV_QUOTE(${CALLERID(name)})},${CSV_QUOTE(${CALLERID(num)})},
    ${CSV_QUOTE(${CALLERID(ANI)})},${CSV_QUOTE(${CALLERID(RDNIS)})},
    ${CSV_QUOTE(${CALLERID(DNID)})},${CSV_QUOTE(${CHANNEL(exten)})},
    ${CSV_QUOTE(${CHANNEL(context)})},${CSV_QUOTE(${CHANNEL(channame)})},
    ${CSV_QUOTE(${CHANNEL(appname)})},${CSV_QUOTE(${CHANNEL(appdata)})},
    ${CSV_QUOTE(${CHANNEL(amaflags)})},${CSV_QUOTE(${CHANNEL(accountcode)})},
    ${CSV_QUOTE(${CHANNEL(uniqueid)})},${CSV_QUOTE(${CHANNEL(linkedid)})},
    ${CSV_QUOTE(${CHANNEL(peer)})},${CSV_QUOTE(${CHANNEL(userfield)})},
    ${CSV_QUOTE(${eventextra})}
The cel_manager
        backend emits CEL events on the Asterisk Manager Interface (we
        discussed the AMI in detail in Chapter 20, Asterisk Manager Interface (AMI)). This module is configured in the /etc/asterisk/cel.conf file. This file
        should contain a single section called [manager], which contains a single option to
        enable this module. The default value is no, but you can enable it as follows:
[manager] enabled = yes
With this configuration in place, CEL events will appear as events on the manager interface. To generate example manager events, we will use the following dialplan example:
exten => 111,1,Answer()
    same => n,CELGenUserEvent(Custom Event,Whiskey Tango Foxtrot)
    same => n,Hangup()
This is the command used to execute this extension and generate sample CEL events:
*CLI>console dial 111@testing
Finally, this is one of the example manager events produced as a result of this test call:
Event: CEL Privilege: call,all EventName: CHAN_START AccountCode: CallerIDnum: CallerIDname: CallerIDani: CallerIDrdnis: CallerIDdnid: Exten: 111 Context: testing Channel: Console/dsp Application: AppData: EventTime: 2010-08-23 08:14:51 AMAFlags: NONE UniqueID: 1282569291.1 LinkedID: 1282569291.1 Userfield: Peer:
This module allows posting of CEL events to a PostgreSQL
        database. We recommend that new installations use cel_odbc instead.
The cel_radius
        backend allows posting of CEL events to a RADIUS server. When using
        this module, each CEL event is reported to the RADIUS server as a
        single stop event. This module is configured in the /etc/asterisk/cel.conf file. The options
        for this module, listed in Table 24.14, “Available options in the cel.conf [radius] section”, are
        placed in a section called [radius].
This CEL backend inserts CEL events into a SQLite database using SQLite version 3. The database created
        by this module lives at /var/log/asterisk/master.db. The
        configuration file for this module, /etc/asterisk/cel_sqlite3_custom.conf,
        identifies the table name, as well as customizes which CEL variables
        will be inserted into the database. It looks like this:
[master]
table = cel
;
; List the column names to use when inserting CEL events.
;
columns => eventtype, eventtime, cidname, cidnum, cidani, cidrdnis, ciddnid,
    context, exten, channame, appname, appdata, amaflags, accountcode, uniqueid,
    userfield, peer
;
; Map CEL event contents to the previously specified columns.
;
values => '${eventtype}','${eventtime}','${CALLERID(name)}','${CALLERID(num)}',
    '${CALLERID(ANI)}','${CALLERID(RDNIS)}','${CALLERID(DNID)}',
    '${CHANNEL(context)}','${CHANNEL(exten)}','${CHANNEL(channame)}',
    '${CHANNEL(appname)}','${CHANNEL(appdata)}','${CHANNEL(amaflags)}',
    '${CHANNEL(accountcode)}','${CHANNEL(uniqueid)}','${CHANNEL(userfield)}',
    '${CHANNEL(peer)}'Now we will show you some example sets of call events from
      the CEL system. The cel_custom module
      will be used for its simplicity. The configuration used for /etc/asterisk/cel_custom.conf is the same as
      shown in the section called “cel_custom”. Additionally, the
      following configuration was used for /etc/asterisk/cel.conf:
[general] enable = yes apps = Dial,Playback events = ALL
In this example, a single phone calls into an extension that plays back a prompt that says “Hello World.” This is the dialplan:
exten => 200,1,Answer()
    same => n,Playback(hello-world)
    same => n,Hangup()
Here are the CEL events that are logged as a result of making this call:
"CHAN_START","1282062437.436130","Julie Bryant","12565553333","","","","200", "LocalSets","SIP/0000FFFF0003-00000010","","","3","","1282062437.17", "1282062437.17","","" "ANSWER","1282062437.436513","Julie Bryant","12565553333","12565553333","", "200","200","LocalSets","SIP/0000FFFF0003-00000010","Answer","","3","", "1282062437.17","1282062437.17","","" "APP_START","1282062437.501868","Julie Bryant","12565553333","12565553333", "","200","200","LocalSets","SIP/0000FFFF0003-00000010","Playback", "hello-world","3","","1282062437.17","1282062437.17","","" "APP_END","1282062439.008997","Julie Bryant","12565553333","12565553333","", "200","200","LocalSets","SIP/0000FFFF0003-00000010","Playback", "hello-world","3","","1282062437.17","1282062437.17","","" "HANGUP","1282062439.009127","Julie Bryant","12565553333","12565553333","", "200","200","LocalSets","SIP/0000FFFF0003-00000010","","","3","", "1282062437.17","1282062437.17","","" "CHAN_END","1282062439.009666","Julie Bryant","12565553333","12565553333", "","200","200","LocalSets","SIP/0000FFFF0003-00000010","","","3","", "1282062437.17","1282062437.17","","" "LINKEDID_END","1282062439.009707","Julie Bryant","12565553333", "12565553333","","200","200","LocalSets","SIP/0000FFFF0003-00000010","", "","3","","1282062437.17","1282062437.17","",""
For the second example, one phone will call another via
        extension 101. This results in a
        call that has two channels that are bridged together. Here is the
        extension that was called in the dialplan:
exten => 101,1,Dial(SIP/0000FFFF0001)
Here are the CEL events that are generated as a result of making this call:
"CHAN_START","1282062455.574611","Julie Bryant","12565553333","","","","101", "LocalSets","SIP/0000FFFF0003-00000011","","","3","","1282062455.18", "1282062455.18","","" "APP_START","1282062455.574872","Julie Bryant","12565553333","12565553333","", "101","101","LocalSets","SIP/0000FFFF0003-00000011","Dial", "SIP/0000FFFF0001","3","","1282062455.18","1282062455.18","","" "CHAN_START","1282062455.575044","Candice Yant","12565551111","","","","s", "LocalSets","SIP/0000FFFF0001-00000012","","","3","","1282062455.19", "1282062455.18","","" "ANSWER","1282062458.068134","","101","12565551111","","","101","LocalSets", "SIP/0000FFFF0001-00000012","AppDial","(Outgoing Line)","3","", "1282062455.19","1282062455.18","","" "ANSWER","1282062458.068361","Julie Bryant","12565553333","12565553333","", "101","101","LocalSets","SIP/0000FFFF0003-00000011","Dial", "SIP/0000FFFF0001","3","","1282062455.18","1282062455.18","","" "BRIDGE_START","1282062458.068388","Julie Bryant","12565553333", "12565553333","","101","101","LocalSets","SIP/0000FFFF0003-00000011", "Dial","SIP/0000FFFF0001","3","","1282062455.18","1282062455.18","","" "BRIDGE_END","1282062462.965704","Julie Bryant","12565553333","12565553333", "","101","101","LocalSets","SIP/0000FFFF0003-00000011","Dial", "SIP/0000FFFF0001","3","","1282062455.18","1282062455.18","","" "HANGUP","1282062462.966097","","101","12565551111","","","","LocalSets", "SIP/0000FFFF0001-00000012","AppDial","(Outgoing Line)","3","", "1282062455.19","1282062455.18","","" "CHAN_END","1282062462.966119","","101","12565551111","","","","LocalSets", "SIP/0000FFFF0001-00000012","AppDial","(Outgoing Line)","3","", "1282062455.19","1282062455.18","","" "APP_END","1282062462.966156","Julie Bryant","12565553333","12565553333","", "101","101","LocalSets","SIP/0000FFFF0003-00000011","Dial", "SIP/0000FFFF0001","3","","1282062455.18","1282062455.18","","" "HANGUP","1282062462.966215","Julie Bryant","12565553333","12565553333", "","101","101","LocalSets","SIP/0000FFFF0003-00000011","","","3","", "1282062455.18","1282062455.18","","" "CHAN_END","1282062462.966418","Julie Bryant","12565553333","12565553333", "","101","101","LocalSets","SIP/0000FFFF0003-00000011","","","3","", "1282062455.18","1282062455.18","","" "LINKEDID_END","1282062462.966441","Julie Bryant","12565553333", "12565553333","","101","101","LocalSets","SIP/0000FFFF0003-00000011", "","","3","","1282062455.18","1282062455.18","",""
In this final example, a transfer will be executed. The
        call is started by calling a phone via extension 102. That call is then transferred to
        another phone at extension 101.
        Here is the relevant dialplan:
exten => 101,1,Dial(SIP/0000FFFF0001) exten => 102,1,Dial(SIP/0000FFFF0002)
Here are the CEL events logged as a result of this call scenario:
"CHAN_START","1282062488.028200","Julie Bryant","12565553333","","","", "102","LocalSets","SIP/0000FFFF0003-00000013","","","3","", "1282062488.20","1282062488.20","","" "APP_START","1282062488.028464","Julie Bryant","12565553333","12565553333", "","102","102","LocalSets","SIP/0000FFFF0003-00000013","Dial", "SIP/0000FFFF0002","3","","1282062488.20","1282062488.20","","" "CHAN_START","1282062488.028762","Brooke Brown","12565552222","","","", "s","LocalSets","SIP/0000FFFF0002-00000014","","","3","","1282062488.21", "1282062488.20","","" "ANSWER","1282062492.565759","","102","12565552222","","","102","LocalSets", "SIP/0000FFFF0002-00000014","AppDial","(Outgoing Line)","3","", "1282062488.21","1282062488.20","","" "ANSWER","1282062492.565973","Julie Bryant","12565553333","12565553333","", "102","102","LocalSets","SIP/0000FFFF0003-00000013","Dial", "SIP/0000FFFF0002","3","","1282062488.20","1282062488.20","","" "BRIDGE_START","1282062492.566001","Julie Bryant","12565553333", "12565553333","","102","102","LocalSets","SIP/0000FFFF0003-00000013", "Dial","SIP/0000FFFF0002","3","","1282062488.20","1282062488.20","","" "CHAN_START","1282062497.940687","","","","","","s","LocalSets", "AsyncGoto/SIP/0000FFFF0002-00000014","","","3","","1282062497.22", "1282062488.20","","" "BLINDTRANSFER","1282062497.940925","Julie Bryant","12565553333","12565553333","", "102","102","LocalSets","SIP/0000FFFF0003-00000013","Dial","SIP/0000FFFF0002", "3","","1282062488.20","1282062488.20", "AsyncGoto/SIP/0000FFFF0002-00000014<ZOMBIE>","" "BRIDGE_END","1282062497.940961","Julie Bryant","12565553333","12565553333","", "102","102","LocalSets","SIP/0000FFFF0003-00000013","Dial", "SIP/0000FFFF0002","3","","1282062488.20","1282062488.20","","" "APP_START","1282062497.941021","","102","12565552222","","","101","LocalSets", "SIP/0000FFFF0002-00000014","Dial","SIP/0000FFFF0001","3","", "1282062497.22","1282062488.20","","" "CHAN_START","1282062497.941207","Candice Yant","12565551111","","","","s", "LocalSets","SIP/0000FFFF0001-00000015","","","3","","1282062497.23", "1282062488.20","","" "HANGUP","1282062497.941361","","","","","","","LocalSets", "AsyncGoto/SIP/0000FFFF0002-00000014<ZOMBIE>","AppDial", "(Outgoing Line)","3","","1282062488.21","1282062488.20","","" "CHAN_END","1282062497.941380","","","","","","","LocalSets", "AsyncGoto/SIP/0000FFFF0002-00000014<ZOMBIE>","AppDial","(Outgoing Line)", "3","","1282062488.21","1282062488.20","","" "APP_END","1282062497.941415","Julie Bryant","12565553333","12565553333","", "102","102","LocalSets","SIP/0000FFFF0003-00000013","Dial", "SIP/0000FFFF0002","3","","1282062488.20","1282062488.20","","" "HANGUP","1282062497.941453","Julie Bryant","12565553333","12565553333", "","102","102","LocalSets","SIP/0000FFFF0003-00000013","","","3","", "1282062488.20","1282062488.20","","" "CHAN_END","1282062497.941474","Julie Bryant","12565553333","12565553333", "","102","102","LocalSets","SIP/0000FFFF0003-00000013","","","3","", "1282062488.20","1282062488.20","","" "ANSWER","1282062500.559578","","101","12565551111","","","101","LocalSets", "SIP/0000FFFF0001-00000015","AppDial","(Outgoing Line)","3","", "1282062497.23","1282062488.20","","" "BRIDGE_START","1282062500.559720","","102","12565552222","","","101","LocalSets", "SIP/0000FFFF0002-00000014","Dial","SIP/0000FFFF0001","3","","1282062497.22", "1282062488.20","","" "BRIDGE_END","1282062512.742600","","102","12565552222","","","101","LocalSets", "SIP/0000FFFF0002-00000014","Dial","SIP/0000FFFF0001","3","","1282062497.22", "1282062488.20","","" "HANGUP","1282062512.743006","","101","12565551111","","","","LocalSets", "SIP/0000FFFF0001-00000015","AppDial","(Outgoing Line)","3","","1282062497.23", "1282062488.20","","" "CHAN_END","1282062512.743211","","101","12565551111","","","","LocalSets", "SIP/0000FFFF0001-00000015","AppDial","(Outgoing Line)","3","","1282062497.23", "1282062488.20","","" "APP_END","1282062512.743286","","102","12565552222","","","101","LocalSets", "SIP/0000FFFF0002-00000014","Dial","SIP/0000FFFF0001","3","","1282062497.22", "1282062488.20","","" "HANGUP","1282062512.743346","","102","12565552222","","","101","LocalSets", "SIP/0000FFFF0002-00000014","","","3","","1282062497.22","1282062488.20", "","" "CHAN_END","1282062512.743371","","102","12565552222","","","101","LocalSets", "SIP/0000FFFF0002-00000014","","","3","","1282062497.22","1282062488.20", "","" "LINKEDID_END","1282062512.743391","","102","12565552222","","","101", "LocalSets","SIP/0000FFFF0002-00000014","","","3","","1282062497.22", "1282062488.20","",""
[172] If you submit a patch to add any of these events to the code and reference this footnote, Russell will send you a free Asterisk t-shirt. Footnote bribery!