Random Bits of Open Code

Check-in [e89d9090b5]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added detailed manager level graphs with sub-users, still missing sub-manager summaries
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:e89d9090b5be2b070b8fd13fbda4a0084686d740
User & Date: jmoon18 2019-05-01 17:20:56
Context
2019-05-10
21:04
Updated margs to be a chicken 5 compatible egg check-in: 48ce9ce1f4 user: jmoon18 tags: margs-chicken-5
2019-05-06
18:09
Merged changes for mtdb to trunk check-in: d63085db62 user: mrwellan tags: trunk
2019-05-01
17:20
Added detailed manager level graphs with sub-users, still missing sub-manager summaries check-in: e89d9090b5 user: jmoon18 tags: trunk
2019-04-29
16:23
Added code for creating team based usage charts. Not working perfectly since large queries are killing sqlite check-in: 4675203d76 user: jmoon18 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ringchart/runstats.scm.

28
29
30
31
32
33
34
35


36
37


38
39
40
41
42
43
44
    (load-all-emps db top-mgr ht)
    (close-database db)
    ht))

;; (use trace)
;; (trace-call-sites #t)
;; (trace db-get-emps get-person-by-id get-rollup-record)



(if (file-exists? ".runstatsrc")(load ".runstatsrc"))
(define *top-mgr* #f)



;; fake out readline usage of toplevel-command
;; (define (toplevel-command . a) #f)
(define (start-repl)
  (import csi)
  (import extras) ;; might not be needed
  ;; (import csi)







<
>
>


>
>







28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46
47
    (load-all-emps db top-mgr ht)
    (close-database db)
    ht))

;; (use trace)
;; (trace-call-sites #t)
;; (trace db-get-emps get-person-by-id get-rollup-record)

(define *ignore-users* #f)
(define *user-list* #f)
(if (file-exists? ".runstatsrc")(load ".runstatsrc"))
(define *top-mgr* #f)
(set! *cstats-ignore-users* *ignore-users*)
(set! *cstats-user-list* *user-list*)

;; fake out readline usage of toplevel-command
;; (define (toplevel-command . a) #f)
(define (start-repl)
  (import csi)
  (import extras) ;; might not be needed
  ;; (import csi)

Changes to ringchart/src/cstats.scm.

28
29
30
31
32
33
34



35
36
37
38
39
40
41
42
43
44
45
46
47
48
...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420

421



422
423
424
425





426
427
428






429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451

452
453
454
455
456
457
458
459
460
461
462
463





464
465
466
467
468
469
470




471



472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
...
499
500
501
502
503
504
505
506


507
508
509
510
511
512
513
...
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532


























































































































533
534
535
536
537
538
539
...
575
576
577
578
579
580
581


582
583
584
585
586
587
588
...
593
594
595
596
597
598
599






600
601
602
603
604
605
606
...
646
647
648
649
650
651
652

653
654


655

656
657


658
659
660
661
662
663
664
665
666




667



668
669













670





671




672
673





 sql-de-lite
 srfi-13
 (prefix sqlite3 sql3:)
 posix
 chicken
 srfi-1
 srfi-69)




;;======================================================================
;; misc crud
;;======================================================================

(define (to-int x)(inexact->exact (round x)))

;;======================================================================
;; Db query/utils
;;======================================================================

(define (open-db fname)
  (let* ((fexists (file-exists? fname))
	 (db      (open-database fname)))
................................................................................
	(close-database db))))


(define (get-rollup-record db id)
  (query fetch-row (sql db "SELECT id,uid,pid,total,cores_tot,actual, cores_act FROM rollup WHERE id=?;") id))


(define (gen-peak-for-user-orig user)
   (let* ((jobs-db  (open-db "jobs.db")))
        (print "Getting peak data for " user)
        (let* ((last-peak-cores 0)
               (highest-peak 0)
               (highest-peak-cores 0)
               (select-stmt (prepare jobs-db "select count(*), sum(num_cpus) from jobs where user=? and start_time <= ? and finish_time > ?")))
          (for-each
            (lambda (job)
              ;;(print job)
              (let* ((myrow  (query fetch-row select-stmt user (car job) (car job))))
                ;;(print myrow)
                (if (not (= last-peak-cores (cadr myrow))) (print (car job) " " myrow))
                (set! last-peak-cores (cadr myrow))
                (if (> (car myrow) highest-peak) (set! highest-peak (car myrow)))
                (if (> (cadr myrow) highest-peak-cores) (set! highest-peak-cores (cadr myrow)))

              )



            )
          (query fetch-rows (sql jobs-db "select distinct start_time from jobs where user=? order by start_time asc limit 20") user) 
          )
          (print "Highest peak for " user " is " highest-peak)





        )
   )
)








(define (gen-peak-for-user-jeff user)
   (let* ((jobs-db  (open-db "jobs.db")))
        (print "Getting peak data for " user)
        (let* ((last-peak-cores 0)
               (highest-peak 0)
               (highest-peak-cores 0)
               (iterator 0)
               (last-sample (current-seconds))
               (previous-time-stamp (current-seconds))
               (select-stmt (prepare jobs-db "select count(*), sum(num_cpus) from jobs where user=? and start_time <= ? and finish_time > ?"))
               (alljobs (query fetch-rows (sql jobs-db "select jobid, start_time, finish_time, num_cpus from jobs where user=? order by start_time asc limit 40000000") user)))
          (print "Number of jobs: " (length+ alljobs))
          (for-each
            (lambda (job)
             (if (< (cadr job) (+ 30 last-sample)) 
              (let* ((job-start-time (cadr job))
                     (qualifying-jobs 
                          (filter (lambda (x)
                              (let* ((my-start (cadr x))
                                     (my-end   (caddr x)))
                                     (if (and (>= job-start-time my-start) (<= job-start-time my-end)) #t #f)

                              )
                             )
                           alljobs)))
              (let* ((cores (apply + (map cadddr qualifying-jobs))))
                ;;(print "Cores: " cores)
                (set! iterator (+ iterator 1))
                (if (= 0 (modulo iterator 10000)) 
                    (begin
                      (print (current-seconds) " " iterator " records/second="  (/ 10000 (- (+ 1 (current-seconds)) previous-time-stamp)) " " (- (current-seconds) previous-time-stamp) " seconds" )
                      (set! previous-time-stamp (current-seconds))
                      (set! alljobs (filter (lambda(x) (if (<= job-start-time (caddr x)) #t #f)) alljobs))
                      (print "Number of jobs left: " (length+ alljobs))





                    )
                )
                (if (> cores highest-peak-cores) (set! highest-peak-cores cores))
              )
              (set! last-sample (current-seconds)) 
              ;;(print "Qualifying jobs: " qualifying-jobs)
              )




              ;;(print "job skipped")



             )
            )
          alljobs
          )
          (print "Highest peak for " user " is " highest-peak)
        )
   )
)

(define (get-employees user)
  (let* ((db (open-db "people.db"))
         (sth (prepare db (conc "SELECT uid from people where mgr_id in (select id from people where uid='" user "' )")))
         (employees (fetch-rows sth)))
         ;;(list user (map get-employees (fetch-rows sth)))
         (if (>= (length+ employees) 1)
           (flatten (append (list user) (map get-employees (map car employees))))
           (list user))
  )
)


(define (gen-peak-for-user user manager)
   (print "User: " user " Manager: " manager)
   (let* ((jobs-db  (open-db "jobs.db"))
          (old-max 0)
          (max-timestamp 0)
................................................................................
          (highest-peak-cores 0)
          (last-peak 0)
          (last-write 0)
          (ht (make-hash-table))
          (filter-users (if manager (get-employees (car user)) user))
          (foo (print "Filter-users: " filter-users))
          (filter-string (conc "('" (string-join filter-users "','")  "')"))
          (sql-query (conc "SELECT * FROM (SELECT num_cpus,start_time AS blah, jobid FROM jobs WHERE user in " filter-string " AND num_cpus > 0 UNION SELECT (0 - num_cpus) AS num_cpus,finish_time AS blah, jobid FROM jobs WHERE user in " filter-string " and num_cpus > 0) ORDER BY blah ASC ;"))


          (sth (prepare jobs-db sql-query)))
         (print "Getting peak data for " user)
         (print "Query: " sql-query)
         (query 
          (fold-rows
           ;;(lambda (res num_cpus event-time jobid)
           (lambda (my-row res)
................................................................................
             ;;(print my-row)
             (let ((newres (+ res (car my-row))))
               (if (> newres old-max) (set! old-max newres))
               (if (> newres old-max) (set! max-timestamp (second my-row)))
               (if (or (= 0 (car my-row)) (= old-max (car my-row)))
                 (begin (hash-table-set! ht (second my-row) newres) (set! last-write (second my-row)))
               )
               (if (or (< 2 (abs (- (car my-row) last-peak))) (> (second my-row) (+ 30 last-write))   )
                 (begin (hash-table-set! ht (second my-row) newres) (set! last-write (second my-row)))
               )
               ;;(print jobid " " event-time " " num_cpus " " newres)
               (set! last-peak (car my-row))
               ;;(print (first my-row) "," newres)
               newres))
             0)
           sth)
          (print "Max: " old-max)
          (list old-max max-timestamp ht)
))



























































































































(define (create-peak-html user peak-data)
  (print "Creating html for: " user)
  (if (not (directory? "peaks"))
    (create-directory "peaks")
  )
  (with-output-to-file (conc "peaks/" (car user) ".html")
................................................................................
      (sort (hash-table-keys (third peak-data)) < ))
(print "  g = new Dygraph(

    // containing div
    document.getElementById('graphdiv'),
    data
  ,{


     axis: { 
       x : { 
         valueFormatter: Dygraph.dateString_,
         valueParser: function(x) { return 1000*parseInt(x); },
         ticker: Dygraph.dateTicker
         }
       },
................................................................................
     title: 'Netbatch Usage over time'
   } 
  );
</script></body></html>")
    )
  ) 
)







(define (create-peak-csv user peak-data)
  (print "Creating csv for: " user)
  (print "Max for " user " is " (first peak-data))
  (if (not (directory? "peaks"))
    (create-directory "peaks")
  )
................................................................................
          #t)
          'immediate
        ))
  )
)

(define (gen-peak-data)

  (let* ((people-db (open-db "people.db")))
    (for-each


      (lambda(user)

        (let* ((peak-data (gen-peak-for-user user #f))
               (peak-data-mgr (gen-peak-for-user user #t)))


          (create-peak-csv user peak-data)
          (create-peak-html  user peak-data)
          (create-peak-csv  (list (conc (car user) "-team")) peak-data-mgr)
          (create-peak-html (list (conc (car user) "-team")) peak-data-mgr)
          (handle-exceptions exn (print "Update-peak-db failed" ((condition-property-accessor 'exn 'message) exn)) (update-peak-db  user peak-data))
          (print "Updated everything for " user)
        )
      )
    (query fetch-rows (sql people-db "select uid from people"))




    )



  ))


























)












>
>
>






<







 







|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
>
|
>
>
>
|
<
|
<
>
>
>
>
>
|
|
|
>
>
>
>
>
>
|
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
|
<
<
<
<
<
<
<
<
<
<
>
>
>
>
>
|
|
<
|
<
<
<
>
>
>
>
|
>
>
>
|
|
<
|
<
|
|
|

<
<
<
<
<
<
<
<
|
<







 







|
>
>







 







|











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>







 







>
>
>
>
>
>







 







>
|
<
>
>
|
>

|
>
>


|
|



|
|
>
>
>
>
|
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>

|
>
>
>
>
>
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
...
400
401
402
403
404
405
406
407
408
409
410
411











412
413
414
415
416
417

418

419
420
421
422
423
424
425
426
427
428
429
430
431
432
433


434
435


















436
437
438










439
440
441
442
443
444
445

446



447
448
449
450
451
452
453
454
455
456

457

458
459
460
461








462

463
464
465
466
467
468
469
...
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
...
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
...
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
...
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
...
750
751
752
753
754
755
756
757
758

759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
 sql-de-lite
 srfi-13
 (prefix sqlite3 sql3:)
 posix
 chicken
 srfi-1
 srfi-69)

(define *cstats-ignore-users* #f)
(define *cstats-user-list* #f)

;;======================================================================
;; misc crud
;;======================================================================

(define (to-int x)(inexact->exact (round x)))

;;======================================================================
;; Db query/utils
;;======================================================================

(define (open-db fname)
  (let* ((fexists (file-exists? fname))
	 (db      (open-database fname)))
................................................................................
	(close-database db))))


(define (get-rollup-record db id)
  (query fetch-row (sql db "SELECT id,uid,pid,total,cores_tot,actual, cores_act FROM rollup WHERE id=?;") id))


(define (get-employees user)
  (let* ((db (open-db "people.db"))
         (sth (prepare db (conc "SELECT uid from people where mgr_id in (select id from people where uid=?)" 
                                (if *cstats-ignore-users* 
                                    (conc "and uid not in (" *cstats-ignore-users* ")")











                                    ""
                                )
                                (if *cstats-user-list* 
                                    (conc "and uid in (" *cstats-user-list* ")")
                                    ""
                                )

                                )))

         (employees (query fetch-rows sth user)))
         ;;(list user (map get-employees (fetch-rows sth)))
         (if (>= (length+ employees) 1)
           (flatten (append (list user) (map get-employees (map car employees))))
           (list user))
  )
)

(define (get-direct-employees user)
  (let* ((db (open-db "people.db"))
         (sth (prepare db (conc "SELECT uid from people where mgr_id in (select id from people where uid=?)"
                                (if *cstats-ignore-users* 
                                    (conc "and uid not in (" *cstats-ignore-users* ")")
                                    ""
                                )


                                (if *cstats-user-list* 
                                    (conc "and uid in (" *cstats-user-list* ")")


















                                    ""
                                )
                           )))










         (employees (query fetch-rows sth user)))
         ;;(list user (map get-employees (fetch-rows sth)))
         (if (>= (length+ employees) 1)
           (flatten (append (list user) (map car employees)))
           (list user))
  )
)





(define (is-manager? user)
  (let* ((db (open-db "people.db"))
         (sth (prepare db "SELECT uid from people where mgr_id in (select id from people where uid=?)"))
         (employees (query fetch-rows sth user)))
        ;;(print employees)
        (if (>= (length+ employees) 1)
            #t
            #f
        )
  )

)

















(define (gen-peak-for-user user manager)
   (print "User: " user " Manager: " manager)
   (let* ((jobs-db  (open-db "jobs.db"))
          (old-max 0)
          (max-timestamp 0)
................................................................................
          (highest-peak-cores 0)
          (last-peak 0)
          (last-write 0)
          (ht (make-hash-table))
          (filter-users (if manager (get-employees (car user)) user))
          (foo (print "Filter-users: " filter-users))
          (filter-string (conc "('" (string-join filter-users "','")  "')"))
          (first-finish-orig (query fetch-value (sql jobs-db "SELECT min(start_time) from jobs")))
          (first-finish 1551108373)
          (sql-query (conc "SELECT * FROM (SELECT sum(num_cpus),start_time AS blah, jobid FROM jobs WHERE user in " filter-string " AND num_cpus > 0 and start_time > " first-finish " group by start_time UNION SELECT (0 - (sum (num_cpus))) AS num_cpus,finish_time AS blah, jobid FROM jobs WHERE user in " filter-string " and num_cpus > 0 and start_time > " first-finish " group by finish_time) ORDER BY blah ASC ;"))
          (sth (prepare jobs-db sql-query)))
         (print "Getting peak data for " user)
         (print "Query: " sql-query)
         (query 
          (fold-rows
           ;;(lambda (res num_cpus event-time jobid)
           (lambda (my-row res)
................................................................................
             ;;(print my-row)
             (let ((newres (+ res (car my-row))))
               (if (> newres old-max) (set! old-max newres))
               (if (> newres old-max) (set! max-timestamp (second my-row)))
               (if (or (= 0 (car my-row)) (= old-max (car my-row)))
                 (begin (hash-table-set! ht (second my-row) newres) (set! last-write (second my-row)))
               )
               (if (or (< 15 (abs (- (car my-row) last-peak))) (> (second my-row) (+ 300 last-write))   )
                 (begin (hash-table-set! ht (second my-row) newres) (set! last-write (second my-row)))
               )
               ;;(print jobid " " event-time " " num_cpus " " newres)
               (set! last-peak (car my-row))
               ;;(print (first my-row) "," newres)
               newres))
             0)
           sth)
          (print "Max: " old-max)
          (list old-max max-timestamp ht)
))


(define (create-peak-stacked-html user peak-data)
  (print "Creating html for: " user)
  (if (not (directory? "peaks"))
    (create-directory "peaks")
  )
  (with-output-to-file (conc "peaks/" user "-stacked.html")
    (lambda()
      (print "<html>
<head>
<script type='text/javascript' src=dygraph.js></script>
<link rel='stylesheet' src='dygraph.css' />
</head>
<body>
<div id='graphdiv'></div>
<div id='legenddiv'></div>
<div id='status' style='width:100%; height:200px;'></div>
<script type='text/javascript'>
  s = document.getElementById('status');
      pts_info = function(e, x, pts) {
        var str = '(' + x + ') ';
        for (var i = 0; i < pts.length; i++) {
          var p = pts[i];
          if (i) str += ', ';
          str += p.name + ': ' + p.yval;
          str += p.name + 'X: ' + p.xval;
        }

	var start=(p.xval/1000)-3600;
	var end = (p.xval/1000)+3600;
        var x = e.offsetX;
        var y = e.offsetY;
        var dataXY = g.toDataCoords(x, y);
        str += ', (' + x + ', ' + y + ')';
        str += ' -> (' + dataXY[0] + ', ' + dataXY[1] + ')';
        str = '<a href=license_by_user-dygraph.php?license=foo&start='+start+'&end='+end+'>Breakdown by large users</a>';
        return str;
      };")
  ;;(print "var data='Date," (string-join (get-employees user) ",")  "\\n';")
      ;;(print (get-employees user))
      (let* ((time-hash (make-hash-table))
             (current-hash (make-hash-table))
             (employee-list (map (lambda(x) (if (and (not (string= x user)) (is-manager? x)) (conc x "-team") x)) (get-direct-employees user)))) 
        ;;(print (delete-duplicates (flatten (map (lambda(username) (hash-table-keys (hash-table-ref/default peak-data username (make-hash-table)))) (get-employees user)))))
        (map (lambda(x) (hash-table-set! time-hash x 1)) (flatten (map (lambda(username) (hash-table-keys (hash-table-ref/default peak-data username (make-hash-table)))) employee-list)))
        (map (lambda (x) (hash-table-set! current-hash x 0)) employee-list) 
        (print "var data='Date," (string-join (hash-table-keys current-hash) ",")  ",Total\\n';")
        (let* ((time-keys (sort (hash-table-keys time-hash) < ))
               (last-update 0)
               (total-peak 0))
           (for-each 
             (lambda (x)
               (map (lambda(emp) 
                      (if (hash-table-exists? (hash-table-ref/default peak-data emp (make-hash-table)) x) 
                         (begin 
                           ;;(print "Setting for :"  emp )
                           ;;(print "Value is : " (hash-table-ref/default (hash-table-ref/default peak-data emp 0) x 0))
                           (hash-table-set! current-hash emp (hash-table-ref/default (hash-table-ref/default peak-data emp 0) x 0))
                         )
                         (begin (if #f (print "Can't find value for: " emp)))
                      )
                     ) 
                employee-list)
                ;;(print "Current-Hash: " (hash-table-values current-hash))
                (let* ((current-peak (fold + 0 (hash-table-values current-hash))))
                   (if (> current-peak total-peak)
                       (begin 
                         ;;(print "New peak at: " x)
                         ;;(print "Values: " (hash-table-values current-hash))
                         (print (conc "data+= new Date(" (* 1000 x) ")+'," (string-join (map number->string (hash-table-values current-hash)) ",") "," (fold + 0 (hash-table-values current-hash)) "\\n';" ))
                         (set! total-peak current-peak))
                         (set! last-update x)
                   )
                )
                (if (> (+ 30 last-update) x) 
                  (begin 
                    (print (conc "data+= new Date(" (* 1000 x) ")+'," (string-join (map number->string (hash-table-values current-hash)) ",") "," (fold + 0 (hash-table-values current-hash)) "\\n';"))
                    (set! last-update x)

                  )
                )
             )
             time-keys
           )
        )

      )
      ;;(for-each (lambda (key)
      ;;  (print "data+= new Date(" (* 1000 key) ") + '," (hash-table-ref/default (third peak-data) key #f) "\\n';")
      ;;)
      ;;(sort (hash-table-keys (third peak-data)) < ))
(print "  g = new Dygraph(

    // containing div
    document.getElementById('graphdiv'),
    data
  ,{
     width: 960,
     height: 320,
     axis: { 
       x : { 
         valueFormatter: Dygraph.dateString_,
         valueParser: function(x) { return 1000*parseInt(x); },
         ticker: Dygraph.dateTicker
         }
       },
     labelsDiv: legenddiv,
     labelsSeparateLines: true,
     stepPlot: true,
     hideOverlayOnMouseOut: false,
     title: 'Netbatch Usage over time'
   } 
  );
</script></body></html>")
    )
  ) 
)





(define (create-peak-html user peak-data)
  (print "Creating html for: " user)
  (if (not (directory? "peaks"))
    (create-directory "peaks")
  )
  (with-output-to-file (conc "peaks/" (car user) ".html")
................................................................................
      (sort (hash-table-keys (third peak-data)) < ))
(print "  g = new Dygraph(

    // containing div
    document.getElementById('graphdiv'),
    data
  ,{
     width: 960,
     height: 640,
     axis: { 
       x : { 
         valueFormatter: Dygraph.dateString_,
         valueParser: function(x) { return 1000*parseInt(x); },
         ticker: Dygraph.dateTicker
         }
       },
................................................................................
     title: 'Netbatch Usage over time'
   } 
  );
</script></body></html>")
    )
  ) 
)







(define (create-peak-csv user peak-data)
  (print "Creating csv for: " user)
  (print "Max for " user " is " (first peak-data))
  (if (not (directory? "peaks"))
    (create-directory "peaks")
  )
................................................................................
          #t)
          'immediate
        ))
  )
)

(define (gen-peak-data)
  ;;(print *cstats-ignore-users*)
  (let* ((people-db (open-db "people.db"))

         (usage-ht (make-hash-table)))
    (query (fold-rows 
      (lambda(user user-xs)
        (print "User: " user )
        (let* ((peak-data (gen-peak-for-user user #f))
               ;;(peak-data-mgr (gen-peak-for-user user #t))
              )
          (hash-table-set! usage-ht (car user) (third peak-data))
          (create-peak-csv user peak-data)
          (create-peak-html  user peak-data)
          ;;(create-peak-csv  (list (conc (car user) "-team")) peak-data-mgr)
          ;;(create-peak-html (list (conc (car user) "-team")) peak-data-mgr)
          (handle-exceptions exn (print "Update-peak-db failed" ((condition-property-accessor 'exn 'message) exn)) (update-peak-db  user peak-data))
          (print "Updated everything for " user)
        )
      ) 0)
    ;;(sql people-db "select uid from people order by uid asc")
    (sql people-db (conc "select uid from people where "
                         (if *cstats-user-list* 
                             (conc "uid in (" *cstats-user-list* ")")
                             (conc "uid not null")
                         )
                         (if *cstats-ignore-users* 
                             (conc "  and uid not in (" *cstats-ignore-users*  ") order by uid asc")
                             (conc "  and 1=1 order by uid asc")
                         )))
    )
    (query (fold-rows 
      (lambda(user user-xs)
        (print "User: " user )
        (let* (  ;;(peak-data (gen-peak-for-user user #f))
               (peak-data-mgr (gen-peak-for-user user #t)))
          (hash-table-set! usage-ht (conc (car user) "-team") (third peak-data-mgr))
          ;;(create-peak-csv user peak-data)
          ;;(create-peak-html  user peak-data)
          (create-peak-csv  (list (conc (car user) "-team")) peak-data-mgr)
          (create-peak-html (list (conc (car user) "-team")) peak-data-mgr)
          (create-peak-stacked-html (car user) usage-ht)
          ;;(handle-exceptions exn (print "Update-peak-db failed" ((condition-property-accessor 'exn 'message) exn)) (update-peak-db  user peak-data))
          (print "Updated everything for " user)
        )
      ) 0)
    (sql people-db (conc "select uid from people where id in (select distinct mgr_id from people) "
                       (if *cstats-user-list* 
                           (conc "and uid in (" *cstats-user-list* ")")
                           (conc "and uid not null")
                        )
                       (if *cstats-ignore-users* 
                           (conc "and uid not in (" *cstats-ignore-users* ") order by uid asc")
                           (conc "and uid not null order by uid asc")
                        )))

    )
    (print (hash-table-keys usage-ht))

  ))

)