one more approach track DLR status via database trigger

Anton Osennikov <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
09.10.2014 12:13, Anton Osennikov ГЇГЁГёГҐГІ:

Hello!

Following is one more approach to track SMS status via database trigger 
(MySQL), based on sqlbox sent_sms table. dlr_url field is required to be 
present and unique to track SMS status.

Attached are scripts to create schema, show SMS completion and wait 
counts, mark stale SMS (no any delivery report too long), do daily clean-up.

-- 
Best regards, Anton Osennikov.
sms-schema.sql (text/plain, 3.6 KB)
/* MySQL table and trigger to track SMS status changes - [email protected] */

--
--

/* find recently sent sms fast */
create index ix_sent_sms_time on sent_sms (time);

/* find sent sms by dlr url fast */
create index ix_sent_sms_dlr_url on sent_sms (dlr_url);

--
--

/* SMS status track */
create table sms_track (
dlr_url varchar(255) primary key, -- SMS key, as dlr url, must be present and unique to track SMS status
sms_id int(10) unique, -- ID of last SMS referring to above URL, MT or DLR
-- sms status, as dlr mask:
dlr_mask int(10) not null, -- 0-created, 8-sent (to SMSC), 1-success, 2-fail, 16-expired (or other error), 4-buffered, 32-intermediate
stale int(1) default 0 not null, -- is SMS stale, due to timeout on local host
create_time datetime not null, -- when SMS was created
update_time datetime not null, -- when SMS status was last updated
valid_time datetime not null   -- when SMS will expire
);

/* */
-- create index ix_sms_track_create_time on sms_track (create_time);

/* find recently updated messages fast */
create index ix_sms_track_update_time on sms_track (update_time);

/* find messages to become stale fast */
create index ix_sms_track_expire_time on sms_track (dlr_mask,valid_time);

delimiter //
--
drop trigger if exists sent_sms_sms_track_ins //

/* */
create trigger sent_sms_sms_track_ins
after insert on sent_sms
for each row
begin
if new.dlr_url is not null and new.time is not null then
    if new.sms_type = 2 then
        insert into sms_track (dlr_url,sms_id,dlr_mask,stale,create_time,update_time,valid_time)
        values (new.dlr_url,new.sql_id,0,0,from_unixtime(new.time),from_unixtime(new.time),
        from_unixtime(new.time + ifnull(new.validity,10800)*60)); -- use 7 days validity by default
    elseif new.sms_type = 3 then
        update sms_track set sms_id = new.sql_id,dlr_mask = new.dlr_mask,update_time = from_unixtime(new.time)
        where dlr_url = new.dlr_url and stale = 0;
    end if;
end if;
end;
//
delimiter ;


/*

-- show track list
select sql_id,smsc_id,sender,receiver,t.dlr_mask,stale,create_time,update_time,valid_time
from sms_track t left join sent_sms s on s.sql_id = t.sms_id where 1=1
-- and smsc_id='mts'
order by create_time desc,sql_id desc limit 25;

-- show wait list
select sql_id,smsc_id,sender,receiver,t.dlr_mask,create_time,
unix_timestamp(now())-unix_timestamp(update_time) elapsed,
unix_timestamp(valid_time)-unix_timestamp(now()) remains
from sms_track t left join sent_sms s on s.sql_id = t.sms_id where 1=1
and t.dlr_mask not in (1,2,16) -- waiting
-- and smsc_id='mts'
order by create_time desc,sql_id desc limit 25;

*/


/*

--
-- save existing data about stale SMS
--
drop table if exists tmp_stale;
create table tmp_stale as select * from sms_track where stale = 1;
select count(*) from tmp_stale;
select * from tmp_stale;

--
-- re-compute sms_track data based on sent_sms data and saved stale SMS data
--
insert into sms_track (dlr_url,sms_id,dlr_mask,stale,create_time,update_time,valid_time)
-- create table tmp_check as
select 
i.dlr_url,
ifnull(t.sms_id,  i.sql_id)   sms_id,
ifnull(t.dlr_mask,s.dlr_mask) dlr_mask,
ifnull(t.stale,0) stale,
ifnull(t.create_time,i.create_time) create_time,
ifnull(t.update_time,i.update_time) update_time,
ifnull(t.valid_time, i.valid_time) valid_time
from (
select dlr_url,
max(sql_id) sql_id,
from_unixtime(min(time)) create_time,
from_unixtime(max(time)) update_time,
from_unixtime(min(time) + ifnull(max(validity),1080)*60) valid_time
from sent_sms 
where sms_type in (2,3) and dlr_url is not null and time is not null
group by dlr_url
) i
join sent_sms s on s.sql_id = i.sql_id
left join tmp_stale t on t.dlr_url = i.dlr_url
;

*/
sms-complete.sql (text/plain, 943 B)
/* show SMS completion stats */

-- only for those messages which processing ended during last round 5 minutes (10:05-10:10 and so on)
-- processing delay is shown as ONE historically first value not exceeding 1 hour

select
count(*) attempt,
count(case when dlr_mask = 1 then 1 else null end) success,
count(case when dlr_mask !=1 then 1 else null end) failure,
ifnull(substring_index(group_concat(case when dlr_mask = 1 and delay < 3600 then delay else null end),',',1),'') delay
from (
 select sms_id,create_time,update_time,unix_timestamp(update_time)-unix_timestamp(create_time) delay,dlr_mask
 from sms_track
 where update_time >= from_unixtime(floor(unix_timestamp(now())/300)*300) - interval 5 minute
 and update_time < from_unixtime(floor(unix_timestamp(now())/300)*300)
-- where update_time >= '2014-10-10 16:45:00' and update_time < '2014-10-10 16:50:00'
 and dlr_mask in (1,2,16) -- 1-success, 2-fail, 16-expired (SMSC fail)
) s
;
sms-wait.sql (text/plain, 514 B)
/* show SMS wait stats */
select count(*) wait_count,round(ifnull(avg(elapsed),0)) avg_elapsed from (
select sql_id,smsc_id,sender,receiver,t.dlr_mask,stale,create_time,
unix_timestamp(now())-unix_timestamp(update_time) elapsed,
unix_timestamp(valid_time)-unix_timestamp(now()) remains
from sms_track t left join sent_sms s on s.sql_id = t.sms_id where 1=1
and t.dlr_mask not in (1,2,16) -- waiting
-- and smsc_id='mts'
) s
where elapsed >= 60 and elapsed < 3600 -- only elapsed time between 1 minute and 1 hour
;
sms-stale.sql (text/plain, 313 B)
--
select now();

-- show messages that are stale
select * from sms_track where dlr_mask not in (1,2,16) and valid_time <= now() - interval 1 minute;

-- mark stale messages
update sms_track set dlr_mask = 16,stale = 1,update_time=now() where dlr_mask not in (1,2,16) and valid_time <= now() - interval 1 minute;
sms-clean.sql (text/plain, 545 B)
/* clean up SMS data track */

--
select now();

-- clean up SMS track
delete from sms_track where update_time <= now() - interval 100 day;

-- clean up sent sms
delete from sent_sms where time <= unix_timestamp(now() - interval 100 day);

-- clean up dlr table from stale SMS data
select d.* from dlr d left join sms_track t on t.dlr_url = d.url and t.stale = 0 where t.dlr_url is null;
delete from dlr where url in (select url from (select d.* from dlr d left join sms_track t on t.dlr_url = d.url and t.stale = 0 where t.dlr_url is null) s);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.