10 #include <client/dbclient.h>
12 #include <boost/lexical_cast.hpp>
14 #include <boost/program_options/options_description.hpp>
15 #include <boost/program_options/parsers.hpp>
16 #include <boost/program_options/variables_map.hpp>
17 #include <boost/timer/timer.hpp>
18 #include <boost/locale.hpp>
21 #include <boost/lambda/lambda.hpp>
25 using namespace mongo
;
27 using namespace boost
;
28 using namespace boost::program_options
;
29 using namespace boost::lambda
;
32 #define DBNAME "admin"
34 #define DBNAME "local"
38 void connect(DBClientConnection
&c
, std::string
const &dsn
, std::string
const &dbname
, std::string
const &user
);
45 lexical_cast
<std::string
>( bool const &v
)
47 return v
? "true" : "false";
53 join( string
const &delim
, vector
<string
> const &list
)
57 for( vector
<string
>::const_iterator ci
= list
.begin(); ci
!= list
.end(); ++ci
)
67 #define EXCEED_TYPE_BOUNDS(TYPE, VAL) \
68 std::numeric_limits<TYPE>::is_integer && \
69 ((VAL > std::numeric_limits<TYPE>::max()) || \
70 (VAL < std::numeric_limits<TYPE>::min()))
74 extract_number(BSONElement
const &e
, string
const &oid
)
82 double tmp
= e
.Double();
83 if( EXCEED_TYPE_BOUNDS(T
, tmp
) )
85 string("double value for ") + oid
+
86 " (" + lexical_cast
<string
>(tmp
) + ") not between " +
87 lexical_cast
<string
>(std::numeric_limits
<T
>::min()) +
89 lexical_cast
<string
>(std::numeric_limits
<T
>::max()));
99 long long tmp
= e
.Int();
100 if( EXCEED_TYPE_BOUNDS(T
, tmp
) )
102 string("int value for ") + oid
+
103 " (" + lexical_cast
<string
>(tmp
) + ") not between " +
104 lexical_cast
<string
>(std::numeric_limits
<T
>::min()) +
106 lexical_cast
<string
>(std::numeric_limits
<T
>::max()));
111 unsigned long long tmp
= e
.Date();
112 if( EXCEED_TYPE_BOUNDS(T
, tmp
) )
114 string("int value for ") + oid
+
115 " (" + lexical_cast
<string
>(tmp
) + ") not between " +
116 lexical_cast
<string
>(std::numeric_limits
<T
>::min()) +
118 lexical_cast
<string
>(std::numeric_limits
<T
>::max()));
123 if( std::numeric_limits
<T
>::max() <= std::numeric_limits
<unsigned int>::max() )
125 unsigned int tmp
= e
.timestampInc();
126 if( EXCEED_TYPE_BOUNDS(T
, tmp
) )
128 string("int value for ") + oid
+
129 " (" + lexical_cast
<string
>(tmp
) + ") not between " +
130 lexical_cast
<string
>(std::numeric_limits
<T
>::min()) +
132 lexical_cast
<string
>(std::numeric_limits
<T
>::max()));
137 unsigned long long tmp
= e
.timestampTime();
138 if( EXCEED_TYPE_BOUNDS(T
, tmp
) )
140 string("int value for ") + oid
+
141 " (" + lexical_cast
<string
>(tmp
) + ") not between " +
142 lexical_cast
<string
>(std::numeric_limits
<T
>::min()) +
144 lexical_cast
<string
>(std::numeric_limits
<T
>::max()));
150 long long tmp
= e
.Long();
151 if( EXCEED_TYPE_BOUNDS(T
, tmp
) )
153 string("long long value for ") + oid
+
154 " (" + lexical_cast
<string
>(tmp
) + ") not between " +
155 lexical_cast
<string
>(std::numeric_limits
<T
>::min()) +
157 lexical_cast
<string
>(std::numeric_limits
<T
>::max()));
163 ss
<< "wrong type for field (" << e
.fieldName() << ") " << e
.type() << " not in "
164 << NumberDouble
<< ", "
167 << Timestamp
<< " or "
169 msgasserted(13111, ss
.str() );
181 OidValueTuple(string
const &an_oid
, unsigned a_type
= ASN_NULL
, string
const &a_value
= string())
189 operator < (OidValueTuple
const &x
, OidValueTuple
const &y
)
191 return x
.oid
< y
.oid
;
196 extract(BSONElement
const &e
, string
const &oid
)
198 return OidValueTuple( oid
);
203 extract
<string
>(BSONElement
const &e
, string
const &oid
)
205 return OidValueTuple( oid
, ASN_OCTET_STR
, e
.String() );
210 extract
<int>(BSONElement
const &e
, string
const &oid
)
212 return OidValueTuple( oid
, ASN_INTEGER
, lexical_cast
<string
>( extract_number
<int>(e
, oid
) ) );
217 extract
<unsigned int>(BSONElement
const &e
, string
const &oid
)
219 return OidValueTuple( oid
, SMI_UINTEGER
, lexical_cast
<string
>( extract_number
<unsigned int>(e
, oid
) ) );
224 extract
<unsigned long long>(BSONElement
const &e
, string
const &oid
)
226 return OidValueTuple( oid
, SMI_COUNTER64
, lexical_cast
<string
>( extract_number
<unsigned long long>(e
, oid
) ) );
231 extract
<double>(BSONElement
const &e
, string
const &oid
)
233 return OidValueTuple( oid
, ASN_OCTET_STR
, lexical_cast
<string
>( extract_number
<double>(e
, oid
) ) );
239 virtual void operator()(BSONElement
const &e
, set
<OidValueTuple
> &out_vals
) = 0;
243 operator << (ostream
&os
, OidValueTuple
const val
)
245 os
<< "(" << val
.oid
<< ", " << val
.type
<< ", " << val
.value
<< ")";
254 ItemExtractor(string
const &oid
)
259 virtual void operator()(BSONElement
const &e
, set
<OidValueTuple
> &out_vals
)
261 out_vals
.insert( extract
<T
>( e
, m_oid
) );
271 struct StructExtractor
275 StructExtractor(map
<string
, Extractor
*> *item_rules
)
277 , m_item_rules(item_rules
)
280 virtual void operator()(BSONElement
const &e
, set
<OidValueTuple
> &out_vals
)
282 BSONObjIterator
i(e
.Obj());
285 BSONElement elem
= i
.next();
286 string fname
= elem
.fieldName();
288 map
<string
, Extractor
*>::iterator iter
= m_item_rules
->find( fname
);
289 if( iter
!= m_item_rules
->end() )
291 Extractor
&ex
= *iter
->second
;
297 virtual void operator()(BSONObj
const &o
, set
<OidValueTuple
> &out_vals
)
299 BSONObjIterator
i(o
.begin());
302 BSONElement elem
= i
.next();
303 string fname
= elem
.fieldName();
305 map
<string
, Extractor
*>::iterator iter
= m_item_rules
->find( fname
);
306 if( iter
!= m_item_rules
->end() )
308 Extractor
&ex
= *iter
->second
;
314 virtual ~StructExtractor()
316 for( map
<string
, Extractor
*>::iterator i
= m_item_rules
->begin();
317 i
!= m_item_rules
->end();
328 map
<string
, Extractor
*> *m_item_rules
;
332 StructExtractor(StructExtractor
const &);
333 StructExtractor
& operator = (StructExtractor
const &);
338 virtual string
operator()() const = 0;
344 StaticAnyfix(string
const &anyfix
)
349 virtual string
operator()() const { return m_anyfix
; }
356 template<class Key
, class Compare
= less
<Key
>, class Allocator
= allocator
<Key
> >
357 std::set
<Key
, Compare
, Allocator
>::iterator
358 insert_or_update( std::set
<Key
, Compare
, Allocator
> &vals
, Key
const &v
)
360 std::set
<Key
, Compare
, Allocator
>::iterator i
= vals
.lower_bound(v
);
361 if( ( i
== vals
.end() ) || ( vals
.key_comp()(v
, *i
) ) )
363 i
= vals
.insert( i
, v
);
367 Key
&ev
= const_cast<Key
&>(*i
);
375 template<class Embed
, class Pre
, class Post
>
376 struct BothfixStructExtractor
380 BothfixStructExtractor(Pre prefix
, Post postfix
)
386 virtual void operator()(BSONElement
const &e
, set
<OidValueTuple
> &out_vals
)
388 set
<OidValueTuple
> ofs_vals
;
389 Embed::operator()(e
, ofs_vals
);
390 apply_fixes(ofs_vals
, out_vals
);
393 void apply_fixes(set
<OidValueTuple
> &collected_vals
, set
<OidValueTuple
> &out_vals
)
395 for( set
<OidValueTuple
>::iterator iter
= collected_vals
.begin();
396 iter
!= collected_vals
.end();
399 OidValueTuple ov
= *iter
;
400 ov
.oid
= m_prefix() + ov
.oid
+ m_postfix();
401 insert_or_update( out_vals
, ov
);
409 std::set
<OidValueTuple
>::iterator
410 insert_or_update( std::set
<OidValueTuple
> &vals
, OidValueTuple
const &v
)
412 std::set
<OidValueTuple
>::iterator i
= vals
.lower_bound(v
);
413 if( ( i
== vals
.end() ) || ( vals
.key_comp()(v
, *i
) ) )
415 i
= vals
.insert( i
, v
);
419 OidValueTuple
&ev
= const_cast<OidValueTuple
&>(*i
);
427 BothfixStructExtractor();
428 BothfixStructExtractor(StructExtractor
const &);
429 BothfixStructExtractor
& operator = (BothfixStructExtractor
const &);
435 friend void swap(RowPostfix
&a
, RowPostfix
&b
);
438 RowPostfix(unsigned row
= 0)
443 virtual string
operator()() const { return "." + lexical_cast
<string
>(m_row
); }
445 operator unsigned() const { return m_row
; }
447 unsigned getRow() const { return m_row
; }
448 unsigned nextRow() { return ++m_row
; }
449 unsigned setNextRow( unsigned next_row
) { return m_row
= next_row
; }
456 swap(RowPostfix
&a
, RowPostfix
&b
)
458 swap(a
.m_row
, b
.m_row
);
462 struct ServReplHostsExtractor
463 : public ItemExtractor
<T
>
466 ServReplHostsExtractor(string
const &type
)
467 : ItemExtractor
<T
>(".2")
471 virtual void operator()(BSONElement
const &e
, set
<OidValueTuple
> &out_vals
)
473 ItemExtractor
<T
>::operator()( e
, out_vals
);
475 out_vals
.insert( OidValueTuple( ".5", ASN_OCTET_STR
, m_type
) );
482 struct ServReplWorkersExtractor
483 : public ServReplHostsExtractor
<string
>
485 ServReplWorkersExtractor()
486 : ServReplHostsExtractor
<string
>("PRIORSEC")
490 struct ServReplArbiterExtractor
491 : public ServReplHostsExtractor
<string
>
493 ServReplArbiterExtractor()
494 : ServReplHostsExtractor
<string
>("ARBITER")
499 struct TableRowExtractor
500 : public BothfixStructExtractor
<E
, const StaticAnyfix
, RowPostfix
&>
503 TableRowExtractor(string
const &tblOid
, RowPostfix
&rowPostfix
, vector
<string
> const &key_chk
= vector
<string
>() )
504 : BothfixStructExtractor
<E
, const StaticAnyfix
, RowPostfix
&>(StaticAnyfix(tblOid
+ ".1"), rowPostfix
)
508 virtual void operator()(BSONElement
const &e
, set
<OidValueTuple
> &out_vals
)
511 set
<OidValueTuple
> embed_vals
;
513 E::operator()(e
, embed_vals
);
514 if( ( merge_row
= find_key(embed_vals
, out_vals
) ) > 0 )
516 RowPostfix
save(merge_row
);
518 swap(save
, this->m_postfix
);
519 this->apply_fixes(embed_vals
, out_vals
);
520 swap(save
, this->m_postfix
);
525 this->m_postfix
.setNextRow( 0 - ( merge_row
- 1 ) );
527 this->m_postfix
.nextRow();
528 this->apply_fixes(embed_vals
, out_vals
);
532 unsigned find_key(set
<OidValueTuple
> const &embed_vals
, set
<OidValueTuple
> &out_vals
) const
535 for( vector
<string
>::const_iterator ci
= m_key_chk
.begin();
536 ci
!= m_key_chk
.end();
539 OidValueTuple
search_key( *ci
, ASN_OCTET_STR
);
540 set
<OidValueTuple
>::iterator cmp_iter
= embed_vals
.lower_bound(search_key
);
541 if( cmp_iter
== embed_vals
.end() )
544 search_key
.value
= cmp_iter
->value
;
545 search_key
.oid
= this->m_prefix() + search_key
.oid
+ ".";
547 for( cmp_iter
= out_vals
.lower_bound(search_key
);
548 ( cmp_iter
!= out_vals
.end() ) && ( 0 == cmp_iter
->oid
.compare( 0, search_key
.oid
.length(), search_key
.oid
) );
551 if( cmp_iter
->value
== search_key
.value
)
553 string row_str
= cmp_iter
->oid
.substr( cmp_iter
->oid
.find_last_of("." ) + 1 );
554 unsigned row
= lexical_cast
<unsigned>(row_str
);
555 if( found
.size() < (row
+1) )
558 if( ci
== m_key_chk
.begin() )
561 found
[row
] = found
[row
] & true;
566 // scan found for first full matching row
568 for( vector
<bool>::iterator vbi
= found
.begin();
580 vector
<string
> m_key_chk
;
587 struct ListRowExtractor
588 : public TableRowExtractor
<E
>
591 ListRowExtractor( string
const &tblOid
, RowPostfix
&rowPostfix
= RowPostfix(), vector
<string
> const &key_chk
= vector
<string
>() )
592 : TableRowExtractor
<E
>( tblOid
, rowPostfix
, key_chk
)
595 virtual void operator()(BSONElement
const &e
, set
<OidValueTuple
> &out_vals
)
597 BSONObjIterator
i(e
.Obj());
600 BSONElement elem
= i
.next();
601 TableRowExtractor
<E
>::operator()(elem
, out_vals
);
607 global_lock_extractors()
609 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
611 extractor_map
->insert( make_pair
<string
, Extractor
*>( "totalTime", new ItemExtractor
<unsigned long long>( ".10.1" ) ) );
612 extractor_map
->insert( make_pair
<string
, Extractor
*>( "lockTime", new ItemExtractor
<unsigned long long>( ".10.2" ) ) );
614 map
<string
, Extractor
*> *current_queue_map
= new map
<string
, Extractor
*>;
615 current_queue_map
->insert( make_pair
<string
, Extractor
*>( "total", new ItemExtractor
<unsigned long long>( ".10.3.1" ) ) );
616 current_queue_map
->insert( make_pair
<string
, Extractor
*>( "readers", new ItemExtractor
<unsigned long long>( ".10.3.2" ) ) );
617 current_queue_map
->insert( make_pair
<string
, Extractor
*>( "writers", new ItemExtractor
<unsigned long long>( ".10.3.3" ) ) );
618 extractor_map
->insert( make_pair
<string
, Extractor
*>( "lockTime", new StructExtractor(current_queue_map
) ) );
620 map
<string
, Extractor
*> *active_clients_map
= new map
<string
, Extractor
*>;
621 active_clients_map
->insert( make_pair
<string
, Extractor
*>( "total", new ItemExtractor
<unsigned long long>( ".10.4.1" ) ) );
622 active_clients_map
->insert( make_pair
<string
, Extractor
*>( "readers", new ItemExtractor
<unsigned long long>( ".10.4.2" ) ) );
623 active_clients_map
->insert( make_pair
<string
, Extractor
*>( "writers", new ItemExtractor
<unsigned long long>( ".10.4.3" ) ) );
624 extractor_map
->insert( make_pair
<string
, Extractor
*>( "lockTime", new StructExtractor(active_clients_map
) ) );
626 return new StructExtractor(extractor_map
);
632 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
634 extractor_map
->insert( make_pair
<string
, Extractor
*>( "bits", new ItemExtractor
<unsigned int>( ".11.1" ) ) );
635 extractor_map
->insert( make_pair
<string
, Extractor
*>( "resident", new ItemExtractor
<unsigned long long>( ".11.2" ) ) );
636 extractor_map
->insert( make_pair
<string
, Extractor
*>( "virtual", new ItemExtractor
<unsigned long long>( ".11.3" ) ) );
637 extractor_map
->insert( make_pair
<string
, Extractor
*>( "supported", new ItemExtractor
<unsigned long long>( ".11.4" ) ) );
638 extractor_map
->insert( make_pair
<string
, Extractor
*>( "mapped", new ItemExtractor
<unsigned long long>( ".11.5" ) ) );
640 return new StructExtractor(extractor_map
);
644 connections_extractors()
646 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
648 extractor_map
->insert( make_pair
<string
, Extractor
*>( "current", new ItemExtractor
<unsigned int>( ".12.1" ) ) );
649 extractor_map
->insert( make_pair
<string
, Extractor
*>( "available", new ItemExtractor
<unsigned long long>( ".12.2" ) ) );
651 return new StructExtractor(extractor_map
);
655 bg_flush_extractors()
657 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
659 extractor_map
->insert( make_pair
<string
, Extractor
*>( "flushes", new ItemExtractor
<unsigned long long>( ".13.1" ) ) );
660 extractor_map
->insert( make_pair
<string
, Extractor
*>( "total_ms", new ItemExtractor
<unsigned long long>( ".13.2" ) ) );
661 extractor_map
->insert( make_pair
<string
, Extractor
*>( "average_ms", new ItemExtractor
<unsigned long long>( ".13.3" ) ) );
662 extractor_map
->insert( make_pair
<string
, Extractor
*>( "last_ms", new ItemExtractor
<unsigned long long>( ".13.4" ) ) );
663 extractor_map
->insert( make_pair
<string
, Extractor
*>( "last_finished", new ItemExtractor
<unsigned long long>( ".13.5" ) ) );
665 return new StructExtractor(extractor_map
);
671 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
673 extractor_map
->insert( make_pair
<string
, Extractor
*>( "totalOpen", new ItemExtractor
<unsigned long long>( ".14.1" ) ) );
674 extractor_map
->insert( make_pair
<string
, Extractor
*>( "clientCursors_size", new ItemExtractor
<unsigned long long>( ".14.2" ) ) );
675 extractor_map
->insert( make_pair
<string
, Extractor
*>( "timedOut", new ItemExtractor
<unsigned long long>( ".14.3" ) ) );
677 return new StructExtractor(extractor_map
);
683 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
685 extractor_map
->insert( make_pair
<string
, Extractor
*>( "bytesIn", new ItemExtractor
<unsigned long long>( ".15.1" ) ) );
686 extractor_map
->insert( make_pair
<string
, Extractor
*>( "bytesOut", new ItemExtractor
<unsigned long long>( ".15.2" ) ) );
687 extractor_map
->insert( make_pair
<string
, Extractor
*>( "numRequests", new ItemExtractor
<unsigned long long>( ".15.3" ) ) );
689 return new StructExtractor(extractor_map
);
693 opcounters_extractors()
695 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
697 extractor_map
->insert( make_pair
<string
, Extractor
*>( "insert", new ItemExtractor
<unsigned long long>( ".16.1" ) ) );
698 extractor_map
->insert( make_pair
<string
, Extractor
*>( "query", new ItemExtractor
<unsigned long long>( ".16.2" ) ) );
699 extractor_map
->insert( make_pair
<string
, Extractor
*>( "update", new ItemExtractor
<unsigned long long>( ".16.3" ) ) );
700 extractor_map
->insert( make_pair
<string
, Extractor
*>( "delete", new ItemExtractor
<unsigned long long>( ".16.4" ) ) );
701 extractor_map
->insert( make_pair
<string
, Extractor
*>( "getmore", new ItemExtractor
<unsigned long long>( ".16.5" ) ) );
702 extractor_map
->insert( make_pair
<string
, Extractor
*>( "command", new ItemExtractor
<unsigned long long>( ".16.6" ) ) );
704 return new StructExtractor(extractor_map
);
710 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
712 extractor_map
->insert( make_pair
<string
, Extractor
*>( "regular", new ItemExtractor
<unsigned long long>( ".17.1" ) ) );
713 extractor_map
->insert( make_pair
<string
, Extractor
*>( "warning", new ItemExtractor
<unsigned long long>( ".17.2" ) ) );
714 extractor_map
->insert( make_pair
<string
, Extractor
*>( "msg", new ItemExtractor
<unsigned long long>( ".17.3" ) ) );
715 extractor_map
->insert( make_pair
<string
, Extractor
*>( "user", new ItemExtractor
<unsigned long long>( ".17.4" ) ) );
716 extractor_map
->insert( make_pair
<string
, Extractor
*>( "rollovers", new ItemExtractor
<unsigned long long>( ".17.5" ) ) );
718 return new StructExtractor(extractor_map
);
722 record_stats_extractors()
724 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
726 extractor_map
->insert( make_pair
<string
, Extractor
*>( "accessesNotInMemory", new ItemExtractor
<unsigned long long>( ".18.1" ) ) );
727 extractor_map
->insert( make_pair
<string
, Extractor
*>( "pageFaultExceptionsThrown", new ItemExtractor
<unsigned long long>( ".18.2" ) ) );
729 return new StructExtractor(extractor_map
);
732 struct LocksExtractor
733 : public StructExtractor
736 LocksExtractor(int row
)
737 : StructExtractor(get_extractor_map(row
))
741 static map
<string
, Extractor
*> *
742 get_extractor_map(int row
)
744 map
<string
, Extractor
*> *overall_map
= new map
<string
, Extractor
*>;
748 map
<string
, Extractor
*> *details_map
= new map
<string
, Extractor
*>;
749 details_map
->insert( make_pair
<string
, Extractor
*>( "R", new ItemExtractor
<unsigned long long>( ".19.1.1" ) ) );
750 details_map
->insert( make_pair
<string
, Extractor
*>( "W", new ItemExtractor
<unsigned long long>( ".19.1.2" ) ) );
751 overall_map
->insert( make_pair
<string
, Extractor
*>( "timeLockedMicros", new StructExtractor(details_map
) ) );
753 details_map
= new map
<string
, Extractor
*>;
754 details_map
->insert( make_pair
<string
, Extractor
*>( "R", new ItemExtractor
<unsigned long long>( ".19.2.1" ) ) );
755 details_map
->insert( make_pair
<string
, Extractor
*>( "W", new ItemExtractor
<unsigned long long>( ".19.2.2" ) ) );
756 overall_map
->insert( make_pair
<string
, Extractor
*>( "timeAcquiringMicros", new StructExtractor(details_map
) ) );
760 map
<string
, Extractor
*> *details_map
= new map
<string
, Extractor
*>;
761 details_map
->insert( make_pair
<string
, Extractor
*>( "r", new ItemExtractor
<unsigned long long>( ".21.1.14." + lexical_cast
<string
>(row
) ) ) );
762 details_map
->insert( make_pair
<string
, Extractor
*>( "w", new ItemExtractor
<unsigned long long>( ".21.1.15." + lexical_cast
<string
>(row
) ) ) );
763 overall_map
->insert( make_pair
<string
, Extractor
*>( "timeLockedMicros", new StructExtractor(details_map
) ) );
765 details_map
= new map
<string
, Extractor
*>;
766 details_map
->insert( make_pair
<string
, Extractor
*>( "r", new ItemExtractor
<unsigned long long>( ".21.1.16." + lexical_cast
<string
>(row
) ) ) );
767 details_map
->insert( make_pair
<string
, Extractor
*>( "w", new ItemExtractor
<unsigned long long>( ".21.1.17." + lexical_cast
<string
>(row
) ) ) );
768 overall_map
->insert( make_pair
<string
, Extractor
*>( "timeAcquiringMicros", new StructExtractor(details_map
) ) );
777 locks_extractors(vector
<string
> const &dbnames
)
779 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
781 extractor_map
->insert( make_pair
<string
, Extractor
*>( ".", new LocksExtractor(0) ) );
783 for( vector
<string
>::const_iterator ci
= dbnames
.begin(); ci
!= dbnames
.end(); ++ci
, ++row
)
784 extractor_map
->insert( make_pair
<string
, Extractor
*>( *ci
, new LocksExtractor(row
) ) );
786 return new StructExtractor(extractor_map
);
790 serv_info_repl_extractors()
792 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
794 extractor_map
->insert( make_pair
<string
, Extractor
*>( "setName", new ItemExtractor
<string
>( ".20.1" ) ) );
795 extractor_map
->insert( make_pair
<string
, Extractor
*>( "ismaster", new ItemExtractor
<int>( ".20.2" ) ) );
796 extractor_map
->insert( make_pair
<string
, Extractor
*>( "secondary", new ItemExtractor
<int>( ".20.3" ) ) );
797 extractor_map
->insert( make_pair
<string
, Extractor
*>( "me", new ItemExtractor
<string
>( ".20.4" ) ) );
798 extractor_map
->insert( make_pair
<string
, Extractor
*>( "primary", new ItemExtractor
<string
>( ".20.5" ) ) );
800 static RowPostfix repl_rows
;
801 vector
<string
> repl_tbl
;
802 repl_tbl
.push_back(".2");
803 extractor_map
->insert( make_pair
<string
, Extractor
*>(
804 "hosts", new ListRowExtractor
<ServReplWorkersExtractor
>(".20.7", repl_rows
, repl_tbl
) ) );
805 extractor_map
->insert( make_pair
<string
, Extractor
*>(
806 "arbiters", new ListRowExtractor
<ServReplArbiterExtractor
>(".20.7", repl_rows
, repl_tbl
) ) );
808 return new StructExtractor(extractor_map
);
812 repl_network_queue_extractors()
814 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
816 extractor_map
->insert( make_pair
<string
, Extractor
*>( "waitTimeMs", new ItemExtractor
<unsigned long long>( ".20.6.1" ) ) );
817 extractor_map
->insert( make_pair
<string
, Extractor
*>( "numElems", new ItemExtractor
<unsigned long long>( ".20.6.2" ) ) );
818 extractor_map
->insert( make_pair
<string
, Extractor
*>( "numBytes", new ItemExtractor
<unsigned long long>( ".20.6.3" ) ) );
820 return new StructExtractor(extractor_map
);
824 server_status_extractors(vector
<string
> const &dbnames
)
826 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
828 extractor_map
->insert( make_pair
<string
, Extractor
*>( "host", new ItemExtractor
<string
>( ".1" ) ) );
829 extractor_map
->insert( make_pair
<string
, Extractor
*>( "version", new ItemExtractor
<string
>( ".2" ) ) );
830 extractor_map
->insert( make_pair
<string
, Extractor
*>( "process", new ItemExtractor
<string
>( ".3" ) ) );
831 extractor_map
->insert( make_pair
<string
, Extractor
*>( "pid", new ItemExtractor
<int>( ".4" ) ) );
832 extractor_map
->insert( make_pair
<string
, Extractor
*>( "uptimeMillis", new ItemExtractor
<unsigned long long>( ".5" ) ) );
834 extractor_map
->insert( make_pair
<string
, Extractor
*>( "globalLock", global_lock_extractors() ) );
835 extractor_map
->insert( make_pair
<string
, Extractor
*>( "mem", mem_extractors() ) );
836 extractor_map
->insert( make_pair
<string
, Extractor
*>( "connections", connections_extractors() ) );
837 extractor_map
->insert( make_pair
<string
, Extractor
*>( "backgroundFlushing", bg_flush_extractors() ) );
838 extractor_map
->insert( make_pair
<string
, Extractor
*>( "cursors", cursors_extractors() ) );
839 extractor_map
->insert( make_pair
<string
, Extractor
*>( "network", network_extractors() ) );
840 extractor_map
->insert( make_pair
<string
, Extractor
*>( "opcounters", opcounters_extractors() ) );
841 extractor_map
->insert( make_pair
<string
, Extractor
*>( "asserts", asserts_extractors() ) );
842 extractor_map
->insert( make_pair
<string
, Extractor
*>( "recordStats", record_stats_extractors() ) );
845 if( serv_status.hasField("locks") && serv_status["locks"].Obj().hasField(dbname.value.c_str()) );
847 BSONObj dbl = serv_status["locks"].Obj().getField(dbname.value).Obj();
849 if( dbl.hasField("timeLockedMicros") )
851 BSONObj o3 = dbl["timeLockedMicros"].Obj();
853 if( o3.hasField("r") )
854 out_vals.insert( extract_uint64( o3["r"], string(".21.1.14.") + row_str ) );
855 if( o3.hasField("w") )
856 out_vals.insert( extract_uint64( o3["w"], string(".21.1.15.") + row_str ) );
859 if( dbl.hasField("timeAcquiringMicros") )
861 BSONObj o3 = dbl["timeAcquiringMicros"].Obj();
863 if( o3.hasField("r") )
864 out_vals.insert( extract_uint64( o3["r"], string(".21.1.16.") + row_str ) );
865 if( o3.hasField("w") )
866 out_vals.insert( extract_uint64( o3["w"], string(".21.1.17.") + row_str ) );
870 extractor_map
->insert( make_pair
<string
, Extractor
*>( "locks", locks_extractors(dbnames
) ) );
871 extractor_map
->insert( make_pair
<string
, Extractor
*>( "repl", serv_info_repl_extractors() ) );
872 extractor_map
->insert( make_pair
<string
, Extractor
*>( "replNetworkQueue", repl_network_queue_extractors() ) );
873 // extractor_map->insert( make_pair<string, Extractor *>( "indexCounters", index_cOunters_extractors() ) );
875 return new StructExtractor(extractor_map
);
878 template<class T1
, class T2
>
879 struct DualItemExtractor
883 DualItemExtractor(string
const &oid1
, string
const &oid2
)
889 virtual void operator()(BSONElement
const &e
, set
<OidValueTuple
> &out_vals
)
891 out_vals
.insert( extract
<T1
>( e
, m_oid1
) );
892 out_vals
.insert( extract
<T2
>( e
, m_oid2
) );
903 struct ReplSetMemberRowExtractor
904 : public StructExtractor
907 ReplSetMemberRowExtractor()
908 : StructExtractor(get_extractor_map())
912 static map
<string
, Extractor
*> *
915 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
917 extractor_map
->insert( make_pair
<string
, Extractor
*>( "_id", new ItemExtractor
<unsigned>( ".1" ) ) );
918 extractor_map
->insert( make_pair
<string
, Extractor
*>( "name", new ItemExtractor
<string
>( ".2" ) ) );
919 extractor_map
->insert( make_pair
<string
, Extractor
*>( "health", new ItemExtractor
<double>( ".3" ) ) );
920 extractor_map
->insert( make_pair
<string
, Extractor
*>( "state", new ItemExtractor
<unsigned>( ".4" ) ) );
921 extractor_map
->insert( make_pair
<string
, Extractor
*>( "stateStr", new ItemExtractor
<string
>( ".5" ) ) );
922 extractor_map
->insert( make_pair
<string
, Extractor
*>( "uptime", new ItemExtractor
<unsigned long long>( ".6" ) ) );
923 extractor_map
->insert( make_pair
<string
, Extractor
*>(
924 "optime", new DualItemExtractor
<unsigned long long, unsigned>( ".7", ".8" ) ) );
925 extractor_map
->insert( make_pair
<string
, Extractor
*>( "pingMs", new ItemExtractor
<unsigned long long>( ".9" ) ) );
926 extractor_map
->insert( make_pair
<string
, Extractor
*>( "lastHeartbeat", new ItemExtractor
<unsigned long long>( ".10" ) ) );
928 return extractor_map
;
933 repl_set_status_extractors()
935 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
937 static RowPostfix repl_rows
;
938 vector
<string
> repl_tbl
;
939 repl_tbl
.push_back(".2");
940 extractor_map
->insert( make_pair
<string
, Extractor
*>(
941 "members", new ListRowExtractor
<ReplSetMemberRowExtractor
>(".20.7", repl_rows
, repl_tbl
) ) );
943 return new StructExtractor(extractor_map
);
946 struct DatabasesMemberRowExtractor
947 : public StructExtractor
950 DatabasesMemberRowExtractor()
951 : StructExtractor(get_extractor_map())
953 , m_cmd(BSONObjBuilder().append("dbstats", 1).obj())
955 , m_dbextractor(get_dbinfo_map())
958 DatabasesMemberRowExtractor(DBClientConnection
*conn
)
959 : StructExtractor(get_extractor_map())
961 , m_cmd(BSONObjBuilder().append("dbstats", 1).obj())
963 , m_dbextractor(get_dbinfo_map())
966 virtual void operator()(BSONElement
const &e
, set
<OidValueTuple
> &out_vals
)
968 StructExtractor::operator() (e
, out_vals
);
970 OidValueTuple
search_key( ".1" ); // ASN.1 type doesn't matter, only OID
971 set
<OidValueTuple
>::iterator cmp_iter
= out_vals
.lower_bound(search_key
);
972 if( m_conn
&& (cmp_iter
!= out_vals
.end()) )
974 m_conn
->runCommand(cmp_iter
->value
, m_cmd
, m_dbinfo
);
975 m_dbextractor(m_dbinfo
, out_vals
);
979 virtual void operator()(BSONObj
const &o
, set
<OidValueTuple
> &out_vals
)
981 StructExtractor::operator() (o
, out_vals
);
983 OidValueTuple
search_key( ".1" ); // ASN.1 type doesn't matter, only OID
984 set
<OidValueTuple
>::iterator cmp_iter
= out_vals
.lower_bound(search_key
);
985 if( m_conn
&& (cmp_iter
!= out_vals
.end()) )
987 m_conn
->runCommand(cmp_iter
->value
, m_cmd
, m_dbinfo
);
988 m_dbextractor(m_dbinfo
, out_vals
);
992 void set_conn(DBClientConnection
*conn
) { m_conn
= conn
; }
995 DBClientConnection
*m_conn
;
996 BSONObj m_cmd
, m_dbinfo
;
997 StructExtractor m_dbextractor
;
999 static map
<string
, Extractor
*> *
1002 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
1004 extractor_map
->insert( make_pair
<string
, Extractor
*>( "name", new ItemExtractor
<string
>( ".1" ) ) );
1005 extractor_map
->insert( make_pair
<string
, Extractor
*>( "sizeOnDisk", new ItemExtractor
<unsigned long long>( ".2" ) ) );
1006 extractor_map
->insert( make_pair
<string
, Extractor
*>( "empty", new ItemExtractor
<int>( ".3" ) ) );
1008 return extractor_map
;
1011 static map
<string
, Extractor
*> *
1014 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
1016 extractor_map
->insert( make_pair
<string
, Extractor
*>( "collections", new ItemExtractor
<unsigned long long>( ".4" ) ) );
1017 extractor_map
->insert( make_pair
<string
, Extractor
*>( "objects", new ItemExtractor
<unsigned long long>( ".5" ) ) );
1018 extractor_map
->insert( make_pair
<string
, Extractor
*>( "avgObjSize", new ItemExtractor
<double>( ".6" ) ) );
1019 extractor_map
->insert( make_pair
<string
, Extractor
*>( "dataSize", new ItemExtractor
<unsigned long long>( ".7" ) ) );
1020 extractor_map
->insert( make_pair
<string
, Extractor
*>( "storageSize", new ItemExtractor
<unsigned long long>( ".8" ) ) );
1021 extractor_map
->insert( make_pair
<string
, Extractor
*>( "numExtents", new ItemExtractor
<unsigned>( ".9" ) ) );
1022 extractor_map
->insert( make_pair
<string
, Extractor
*>( "indexes", new ItemExtractor
<unsigned>( ".10" ) ) );
1023 extractor_map
->insert( make_pair
<string
, Extractor
*>( "sizeOnDisk", new ItemExtractor
<unsigned>( ".11" ) ) );
1024 extractor_map
->insert( make_pair
<string
, Extractor
*>( "fileSize", new ItemExtractor
<unsigned long long>( ".12" ) ) );
1025 extractor_map
->insert( make_pair
<string
, Extractor
*>( "nsSizeMB", new ItemExtractor
<unsigned>( ".13" ) ) );
1027 return extractor_map
;
1032 databases_extractors(DBClientConnection
&conn
)
1034 map
<string
, Extractor
*> *extractor_map
= new map
<string
, Extractor
*>;
1036 static RowPostfix db_rows
;
1037 vector
<string
> db_tbl
;
1038 db_tbl
.push_back(".1");
1039 ListRowExtractor
<DatabasesMemberRowExtractor
> *lre
= new ListRowExtractor
<DatabasesMemberRowExtractor
>(".21", db_rows
, db_tbl
);
1040 lre
->set_conn(&conn
);
1041 extractor_map
->insert( make_pair
<string
, Extractor
*>( "databases", lre
) );
1043 return new StructExtractor(extractor_map
);
1047 collect(DBClientConnection
&c
, set
<OidValueTuple
> &out_vals
)
1049 BSONObj serv_status
, dbases
, repl_info
, cmd
;
1050 StructExtractor
*bson_extractor
= 0;
1052 cmd
= BSONObjBuilder().append("listDatabases", 1).obj();
1053 c
.runCommand(DBNAME
, cmd
, dbases
);
1055 bson_extractor
= databases_extractors(c
);
1056 (*bson_extractor
)(dbases
, out_vals
);
1058 // XXX extract row + dbname for serv_status.locks[]
1059 vector
<string
> database_names
;
1060 OidValueTuple
search_key(".21.1.1.");
1061 for( set
<OidValueTuple
>::iterator cmp_iter
= out_vals
.lower_bound(search_key
);
1062 ( cmp_iter
!= out_vals
.end() ) && ( 0 == cmp_iter
->oid
.compare( 0, search_key
.oid
.length(), search_key
.oid
) );
1065 database_names
.push_back(cmp_iter
->value
);
1068 cmd
= BSONObjBuilder().append( "serverStatus", 1 ).obj();
1069 c
.runCommand(DBNAME
, cmd
, serv_status
);
1071 bson_extractor
= server_status_extractors(database_names
);
1072 (*bson_extractor
)(serv_status
, out_vals
);
1074 cmd
= BSONObjBuilder().append("replSetGetStatus", 1).obj();
1075 c
.runCommand(DBNAME
, cmd
, repl_info
);
1077 bson_extractor
= repl_set_status_extractors();
1078 (*bson_extractor
)(repl_info
, out_vals
);
1082 dump(set
<OidValueTuple
> const &out_vals
)
1084 vector
<string
> result
;
1085 result
.reserve(out_vals
.size() + 2);
1086 for( set
<OidValueTuple
>::iterator iter
= out_vals
.begin();
1087 iter
!= out_vals
.end();
1090 std::string s
= " [ \"";
1094 s
+= lexical_cast
<string
>(iter
->type
);
1096 if( ASN_OCTET_STR
== iter
->type
)
1098 if( ASN_NULL
== iter
->type
)
1100 else if( ASN_OCTET_STR
== iter
->type
)
1101 s
+= boost::locale::conv::utf_to_utf
<char>(iter
->value
);
1104 if( ASN_OCTET_STR
== iter
->type
)
1108 result
.push_back(s
);
1112 << join(",\n", result
) << endl
1117 main(int argc
, char *argv
[])
1121 options_description
desc("Allowed options");
1123 ("help", "produce help message")
1124 ("dsn", value
<string
>(), "set mongodb dsn")
1127 store( parse_command_line( argc
, argv
, desc
), vm
);
1130 if( vm
.count("help") )
1132 cout
<< desc
<< endl
;
1136 if( vm
.count("dsn") == 0 )
1138 cerr
<< desc
<< endl
;
1142 set
<OidValueTuple
> out_vals
;
1144 DBClientConnection c
;
1146 boost::timer::cpu_timer db_dur
;
1148 connect(c
, vm
["dsn"].as
<string
>(), DBNAME
, "admin");
1149 collect(c
, out_vals
);
1152 OidValueTuple
val( ".99.1", SMI_COUNTER64
);
1153 val
.value
= lexical_cast
<string
>( db_dur
.elapsed().user
);
1154 out_vals
.insert( val
);
1157 val
.value
= lexical_cast
<string
>( db_dur
.elapsed().system
);
1158 out_vals
.insert( val
);
1161 val
.value
= lexical_cast
<string
>( db_dur
.elapsed().wall
);
1162 out_vals
.insert( val
);
1167 catch( DBException
&e
)
1169 cout
<< "caught " << e
.what() << endl
;