traceview 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rubocop.yml +5 -0
  4. data/.travis.yml +58 -0
  5. data/Appraisals +10 -0
  6. data/CHANGELOG.md +490 -0
  7. data/CONFIG.md +16 -0
  8. data/Gemfile +95 -0
  9. data/LICENSE +199 -0
  10. data/README.md +380 -0
  11. data/Rakefile +109 -0
  12. data/examples/DNT.md +35 -0
  13. data/examples/carrying_context.rb +225 -0
  14. data/examples/instrumenting_metal_controller.rb +8 -0
  15. data/examples/puma_on_heroku_config.rb +17 -0
  16. data/examples/tracing_async_threads.rb +125 -0
  17. data/examples/tracing_background_jobs.rb +52 -0
  18. data/examples/tracing_forked_processes.rb +100 -0
  19. data/examples/unicorn_on_heroku_config.rb +28 -0
  20. data/ext/oboe_metal/extconf.rb +61 -0
  21. data/ext/oboe_metal/noop/noop.c +7 -0
  22. data/ext/oboe_metal/src/bson/bson.h +221 -0
  23. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  24. data/ext/oboe_metal/src/oboe.h +275 -0
  25. data/ext/oboe_metal/src/oboe.hpp +352 -0
  26. data/ext/oboe_metal/src/oboe_wrap.cxx +3886 -0
  27. data/ext/oboe_metal/tests/test.rb +11 -0
  28. data/gemfiles/mongo.gemfile +33 -0
  29. data/gemfiles/moped.gemfile +33 -0
  30. data/get_version.rb +5 -0
  31. data/init.rb +4 -0
  32. data/lib/joboe_metal.rb +206 -0
  33. data/lib/oboe.rb +7 -0
  34. data/lib/oboe/README +2 -0
  35. data/lib/oboe/backward_compatibility.rb +59 -0
  36. data/lib/oboe/inst/rack.rb +11 -0
  37. data/lib/oboe_metal.rb +151 -0
  38. data/lib/rails/generators/traceview/install_generator.rb +76 -0
  39. data/lib/rails/generators/traceview/templates/traceview_initializer.rb +159 -0
  40. data/lib/traceview.rb +62 -0
  41. data/lib/traceview/api.rb +18 -0
  42. data/lib/traceview/api/layerinit.rb +51 -0
  43. data/lib/traceview/api/logging.rb +209 -0
  44. data/lib/traceview/api/memcache.rb +31 -0
  45. data/lib/traceview/api/profiling.rb +50 -0
  46. data/lib/traceview/api/tracing.rb +135 -0
  47. data/lib/traceview/api/util.rb +121 -0
  48. data/lib/traceview/base.rb +225 -0
  49. data/lib/traceview/config.rb +238 -0
  50. data/lib/traceview/frameworks/grape.rb +97 -0
  51. data/lib/traceview/frameworks/padrino.rb +64 -0
  52. data/lib/traceview/frameworks/padrino/templates.rb +58 -0
  53. data/lib/traceview/frameworks/rails.rb +145 -0
  54. data/lib/traceview/frameworks/rails/helpers/rum/rum_ajax_header.js.erb +5 -0
  55. data/lib/traceview/frameworks/rails/helpers/rum/rum_footer.js.erb +1 -0
  56. data/lib/traceview/frameworks/rails/helpers/rum/rum_header.js.erb +3 -0
  57. data/lib/traceview/frameworks/rails/inst/action_controller.rb +216 -0
  58. data/lib/traceview/frameworks/rails/inst/action_view.rb +56 -0
  59. data/lib/traceview/frameworks/rails/inst/action_view_2x.rb +54 -0
  60. data/lib/traceview/frameworks/rails/inst/action_view_30.rb +48 -0
  61. data/lib/traceview/frameworks/rails/inst/active_record.rb +24 -0
  62. data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  63. data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
  64. data/lib/traceview/frameworks/rails/inst/connection_adapters/oracle.rb +18 -0
  65. data/lib/traceview/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
  66. data/lib/traceview/frameworks/rails/inst/connection_adapters/utils.rb +117 -0
  67. data/lib/traceview/frameworks/sinatra.rb +95 -0
  68. data/lib/traceview/frameworks/sinatra/templates.rb +56 -0
  69. data/lib/traceview/inst/cassandra.rb +279 -0
  70. data/lib/traceview/inst/dalli.rb +86 -0
  71. data/lib/traceview/inst/em-http-request.rb +99 -0
  72. data/lib/traceview/inst/excon.rb +111 -0
  73. data/lib/traceview/inst/faraday.rb +73 -0
  74. data/lib/traceview/inst/http.rb +87 -0
  75. data/lib/traceview/inst/httpclient.rb +173 -0
  76. data/lib/traceview/inst/memcache.rb +102 -0
  77. data/lib/traceview/inst/memcached.rb +94 -0
  78. data/lib/traceview/inst/mongo.rb +238 -0
  79. data/lib/traceview/inst/moped.rb +474 -0
  80. data/lib/traceview/inst/rack.rb +122 -0
  81. data/lib/traceview/inst/redis.rb +271 -0
  82. data/lib/traceview/inst/resque.rb +192 -0
  83. data/lib/traceview/inst/rest-client.rb +38 -0
  84. data/lib/traceview/inst/sequel.rb +162 -0
  85. data/lib/traceview/inst/typhoeus.rb +102 -0
  86. data/lib/traceview/instrumentation.rb +21 -0
  87. data/lib/traceview/loading.rb +94 -0
  88. data/lib/traceview/logger.rb +41 -0
  89. data/lib/traceview/method_profiling.rb +84 -0
  90. data/lib/traceview/ruby.rb +36 -0
  91. data/lib/traceview/support.rb +113 -0
  92. data/lib/traceview/thread_local.rb +26 -0
  93. data/lib/traceview/util.rb +250 -0
  94. data/lib/traceview/version.rb +16 -0
  95. data/lib/traceview/xtrace.rb +90 -0
  96. data/test/frameworks/apps/grape_nested.rb +30 -0
  97. data/test/frameworks/apps/grape_simple.rb +24 -0
  98. data/test/frameworks/apps/padrino_simple.rb +45 -0
  99. data/test/frameworks/apps/sinatra_simple.rb +24 -0
  100. data/test/frameworks/grape_test.rb +142 -0
  101. data/test/frameworks/padrino_test.rb +30 -0
  102. data/test/frameworks/sinatra_test.rb +30 -0
  103. data/test/instrumentation/cassandra_test.rb +380 -0
  104. data/test/instrumentation/dalli_test.rb +171 -0
  105. data/test/instrumentation/em_http_request_test.rb +86 -0
  106. data/test/instrumentation/excon_test.rb +207 -0
  107. data/test/instrumentation/faraday_test.rb +235 -0
  108. data/test/instrumentation/http_test.rb +140 -0
  109. data/test/instrumentation/httpclient_test.rb +296 -0
  110. data/test/instrumentation/memcache_test.rb +251 -0
  111. data/test/instrumentation/memcached_test.rb +226 -0
  112. data/test/instrumentation/mongo_test.rb +462 -0
  113. data/test/instrumentation/moped_test.rb +496 -0
  114. data/test/instrumentation/rack_test.rb +116 -0
  115. data/test/instrumentation/redis_hashes_test.rb +265 -0
  116. data/test/instrumentation/redis_keys_test.rb +318 -0
  117. data/test/instrumentation/redis_lists_test.rb +310 -0
  118. data/test/instrumentation/redis_misc_test.rb +160 -0
  119. data/test/instrumentation/redis_sets_test.rb +293 -0
  120. data/test/instrumentation/redis_sortedsets_test.rb +325 -0
  121. data/test/instrumentation/redis_strings_test.rb +333 -0
  122. data/test/instrumentation/resque_test.rb +62 -0
  123. data/test/instrumentation/rest-client_test.rb +294 -0
  124. data/test/instrumentation/sequel_mysql2_test.rb +326 -0
  125. data/test/instrumentation/sequel_mysql_test.rb +326 -0
  126. data/test/instrumentation/sequel_pg_test.rb +330 -0
  127. data/test/instrumentation/typhoeus_test.rb +285 -0
  128. data/test/minitest_helper.rb +187 -0
  129. data/test/profiling/method_test.rb +198 -0
  130. data/test/servers/rackapp_8101.rb +22 -0
  131. data/test/support/backcompat_test.rb +269 -0
  132. data/test/support/config_test.rb +128 -0
  133. data/test/support/dnt_test.rb +73 -0
  134. data/test/support/liboboe_settings_test.rb +104 -0
  135. data/test/support/xtrace_test.rb +35 -0
  136. data/traceview.gemspec +29 -0
  137. metadata +250 -0
@@ -0,0 +1,52 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ Bundler.require
5
+
6
+ # Make sure oboe is at the bottom of your Gemfile.
7
+ # This is likely redundant but just in case.
8
+ require 'oboe'
9
+
10
+ # Tracing mode can be 'never', 'through' (to follow upstream) or 'always'
11
+ Oboe::Config[:tracing_mode] = 'always'
12
+
13
+ #
14
+ # Update April 9, 2015 - this is done automagically now
15
+ # and doesn't have to be called manually
16
+ #
17
+ # Load library instrumentation to auto-capture stuff we know about...
18
+ # e.g. ActiveRecord, Cassandra, Dalli, Redis, memcache, mongo
19
+ # Oboe::Ruby.load
20
+
21
+ # Some KVs to report to the dashboard
22
+ report_kvs = {}
23
+ report_kvs[:command_line_params] = ARGV.to_s
24
+ report_kvs[:user_id] = `whoami`
25
+
26
+ Oboe::API.start_trace('my_background_job', nil, report_kvs ) do
27
+ #
28
+ # Initialization code
29
+ #
30
+
31
+ tasks = get_all_tasks
32
+
33
+ tasks.each do |t|
34
+ # Optional: Here we embed another 'trace' to separate actual
35
+ # work for each task. In the TV dashboard, this will show
36
+ # up as a large 'my_background_job' parent layer with many
37
+ # child 'task" layers.
38
+ Oboe::API.trace('task', { :task_id => t.id }) do
39
+ t.perform
40
+ end
41
+ end
42
+ #
43
+ # cleanup code
44
+ #
45
+ end
46
+
47
+ # Note that we use 'start_trace' in the outer block and 'trace' for
48
+ # any sub-blocks of code we wish to instrument. The arguments for
49
+ # both methods vary slightly. Details in RubyDoc:
50
+ # https://www.omniref.com/ruby/gems/oboe/2.7.10.1/symbols/Oboe::API::Tracing#tab=Methods
51
+
52
+
@@ -0,0 +1,100 @@
1
+ #
2
+ # This sample demonstrates how to instrument a main loop that
3
+ # retrieves work and calls fork to do the actual work
4
+ #
5
+
6
+ require 'math'
7
+ require 'oboe'
8
+
9
+ Oboe::Config[:tracing_mode] = :always
10
+ Oboe::Config[:verbose] = true
11
+
12
+ # The parent process/loop which collects data
13
+ while true do
14
+
15
+ # For each loop, we instrument the work retrieval. These traces
16
+ # will show up as layer 'get_the_work'.
17
+ Oboe::API.start_trace('get_the_work') do
18
+
19
+ work = get_the_work
20
+
21
+ # Loop through work and pass to `do_the_work` method
22
+ # that spawns a thread each time
23
+ work.each do |job|
24
+ fork do
25
+ # Since the context is copied from the parent process, we clear it
26
+ # and start a new trace via `Oboe::API.start_trace`.
27
+ Oboe::Context.clear
28
+ result = nil
29
+
30
+ Oboe::API.start_trace('do_the_work', nil, :job_id => job.id) do
31
+ result = do_the_work(job)
32
+ end
33
+
34
+ result
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ ##
41
+ # get_the_work
42
+ #
43
+ # Method to retrieve work to do
44
+ #
45
+ def get_the_work
46
+ # We'll just return random integers as a
47
+ # fake work load
48
+ w = []
49
+ w << rand(25)
50
+ w << rand(25)
51
+ w << rand(25)
52
+ end
53
+
54
+ ##
55
+ # do_the_work
56
+ #
57
+ # The work-horse method
58
+ #
59
+ def do_the_work(job_to_do)
60
+ i = job_to_do
61
+ i * Math::PI
62
+ end
63
+
64
+ #########################################################################
65
+ # Notes
66
+ #########################################################################
67
+
68
+ # If your parent process only forks a small number of processes per loop (< 5..10),
69
+ # you may want to mark the child traces as asynchronous and have them directly
70
+ # linked to the parent tracing context.
71
+ #
72
+ # The benefit of this is that instead of having two independent traces (parent
73
+ # and child), you will have a single view of the parent trace showing the
74
+ # spawned child process and it's performance in the TraceView dashboard.
75
+ #
76
+ # To do this:
77
+ # 1. Don't clear the context in the child process
78
+ # 2. Use `Oboe::API.trace` instead
79
+ # 3. Pass the `Async` flag to mark this child as asynchronous
80
+ #
81
+ while true do
82
+ Oboe::API.start_trace('get_the_work') do
83
+
84
+ work = get_the_work
85
+
86
+ work.each do |job|
87
+ fork do
88
+ result = nil
89
+ # 1 Don't clear context
90
+ # 2 Use `Oboe::API.trace` instead
91
+ # 3 Pass the Async flag
92
+ Oboe::API.trace('do_the_work', { :job_id => job.id, 'Async' => 1 }) do
93
+ result = do_the_work(job)
94
+ end
95
+
96
+ result
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,28 @@
1
+ worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
2
+ timeout 15
3
+ preload_app true
4
+
5
+ before_fork do |server, worker|
6
+ Signal.trap 'TERM' do
7
+ puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
8
+ Process.kill 'QUIT', Process.pid
9
+ end
10
+
11
+ defined?(ActiveRecord::Base) and
12
+ ActiveRecord::Base.connection.disconnect!
13
+
14
+ defined?(::Oboe) and
15
+ ::Oboe.disconnect!
16
+ end
17
+
18
+ after_fork do |server, worker|
19
+ Signal.trap 'TERM' do
20
+ puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
21
+ end
22
+
23
+ defined?(ActiveRecord::Base) and
24
+ ActiveRecord::Base.establish_connection
25
+
26
+ defined?(::Oboe) and
27
+ ::Oboe.reconnect!
28
+ end
@@ -0,0 +1,61 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'mkmf'
5
+ require 'rbconfig'
6
+
7
+ # Check if we're running in JRuby
8
+ jruby = defined?(JRUBY_VERSION) ? true : false
9
+
10
+ openshift = ENV.key?('OPENSHIFT_TRACEVIEW_DIR')
11
+
12
+ # When on OpenShift, set the mkmf lib paths so we have no issues linking to
13
+ # the TraceView libs.
14
+ if openshift
15
+ tv_lib64 = "#{ENV['OPENSHIFT_TRACEVIEW_DIR']}usr/lib64"
16
+ tv_tlyzer = "#{ENV['OPENSHIFT_TRACEVIEW_DIR']}usr/lib64/tracelyzer"
17
+
18
+ idefault = "#{ENV['OPENSHIFT_TRACEVIEW_DIR']}usr/include"
19
+ ldefault = "#{tv_lib64}:#{tv_tlyzer}"
20
+
21
+ dir_config('oboe', idefault, ldefault)
22
+ else
23
+ dir_config('oboe')
24
+ end
25
+
26
+ if jruby || ENV.key?('TRACEVIEW_URL')
27
+ # Build the noop extension under JRuby and Heroku.
28
+ # The oboe-heroku gem builds it's own c extension which links to
29
+ # libs specific to a Heroku dyno
30
+ # FIXME: For JRuby we need to remove the c extension entirely
31
+ create_makefile('oboe_noop', 'noop')
32
+
33
+ elsif have_library('oboe', 'oboe_config_get_revision', 'oboe/oboe.h')
34
+
35
+ $libs = append_library($libs, 'oboe')
36
+ $libs = append_library($libs, 'stdc++')
37
+
38
+ $CFLAGS << " #{ENV['CFLAGS']}"
39
+ $CPPFLAGS << " #{ENV['CPPFLAGS']}"
40
+ $LIBS << " #{ENV['LIBS']}"
41
+
42
+ # On OpenShift user rpath to point out the TraceView libraries
43
+ if openshift
44
+ $LDFLAGS << " #{ENV['LDFLAGS']} -Wl,-rpath=#{tv_lib64},--rpath=#{tv_tlyzer}"
45
+ end
46
+
47
+ if RUBY_VERSION < '1.9'
48
+ cpp_command('g++')
49
+ $CPPFLAGS << '-I./src/'
50
+ end
51
+ create_makefile('oboe_metal', 'src')
52
+
53
+ else
54
+ if have_library('oboe')
55
+ $stderr.puts 'Error: The oboe gem requires an updated liboboe. Please update your liboboe packages.'
56
+ end
57
+
58
+ $stderr.puts 'Error: Could not find the base liboboe libraries. No tracing will occur.'
59
+ create_makefile('oboe_noop', 'noop')
60
+ end
61
+
@@ -0,0 +1,7 @@
1
+ #include <ruby.h>
2
+
3
+ /* ruby calls this to load the extension */
4
+ void Init_oboe_noop(void) {
5
+ /* assume we haven't yet defined Hola */
6
+ VALUE klass = rb_define_class("OboeNoop", rb_cObject);
7
+ }
@@ -0,0 +1,221 @@
1
+ /* bson.h */
2
+
3
+ /* Copyright 2009, 2010 10gen Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #ifndef _BSON_H_
19
+ #define _BSON_H_
20
+
21
+ #define MONGO_HAVE_STDINT
22
+ #include "platform_hacks.h"
23
+ #include <time.h>
24
+
25
+ MONGO_EXTERN_C_START
26
+
27
+ typedef enum {
28
+ bson_error=-1,
29
+ bson_eoo=0,
30
+ bson_double=1,
31
+ bson_string=2,
32
+ bson_object=3,
33
+ bson_array=4,
34
+ bson_bindata=5,
35
+ bson_undefined=6,
36
+ bson_oid=7,
37
+ bson_bool=8,
38
+ bson_date=9,
39
+ bson_null=10,
40
+ bson_regex=11,
41
+ bson_dbref=12, /* deprecated */
42
+ bson_code=13,
43
+ bson_symbol=14,
44
+ bson_codewscope=15,
45
+ bson_int = 16,
46
+ bson_timestamp = 17,
47
+ bson_long = 18
48
+ } bson_type;
49
+
50
+ typedef int bson_bool_t;
51
+
52
+ typedef struct {
53
+ char * data;
54
+ bson_bool_t owned;
55
+ } bson;
56
+
57
+ typedef struct {
58
+ const char * cur;
59
+ bson_bool_t first;
60
+ } bson_iterator;
61
+
62
+ typedef struct {
63
+ char * buf;
64
+ char * cur;
65
+ int bufSize;
66
+ bson_bool_t finished;
67
+ int stack[32];
68
+ int stackPos;
69
+ } bson_buffer;
70
+
71
+ #pragma pack(1)
72
+ typedef union{
73
+ char bytes[12];
74
+ int ints[3];
75
+ } bson_oid_t;
76
+ #pragma pack()
77
+
78
+ typedef int64_t bson_date_t; /* milliseconds since epoch UTC */
79
+
80
+ /* ----------------------------
81
+ READING
82
+ ------------------------------ */
83
+
84
+
85
+ bson * bson_empty(bson * obj); /* returns pointer to static empty bson object */
86
+ int bson_copy(bson* out, const bson* in); /* puts data in new buffer. NOOP if out==NULL */
87
+ bson * bson_from_buffer(bson * b, bson_buffer * buf);
88
+ bson * bson_init( bson * b , char * data , bson_bool_t mine );
89
+ bson * bson_init_safe( bson * b , char * data , bson_bool_t mine , size_t buflen);
90
+ int bson_size(const bson * b );
91
+ void bson_destroy( bson * b );
92
+
93
+ void bson_print( bson * b );
94
+ void bson_print_raw( const char * bson , int depth );
95
+
96
+ /* advances iterator to named field */
97
+ /* returns bson_eoo (which is false) if field not found */
98
+ bson_type bson_find(bson_iterator* it, const bson* obj, const char* name);
99
+
100
+ void bson_iterator_init( bson_iterator * i , const char * bson );
101
+
102
+ /* more returns true for eoo. best to loop with bson_iterator_next(&it) */
103
+ bson_bool_t bson_iterator_more( const bson_iterator * i );
104
+ bson_type bson_iterator_next( bson_iterator * i );
105
+
106
+ bson_type bson_iterator_type( const bson_iterator * i );
107
+ const char * bson_iterator_key( const bson_iterator * i );
108
+ const char * bson_iterator_value( const bson_iterator * i );
109
+
110
+ /* these convert to the right type (return 0 if non-numeric) */
111
+ double bson_iterator_double( const bson_iterator * i );
112
+ int bson_iterator_int( const bson_iterator * i );
113
+ int64_t bson_iterator_long( const bson_iterator * i );
114
+
115
+ /* false: boolean false, 0 in any type, or null */
116
+ /* true: anything else (even empty strings and objects) */
117
+ bson_bool_t bson_iterator_bool( const bson_iterator * i );
118
+
119
+ /* these assume you are using the right type */
120
+ double bson_iterator_double_raw( const bson_iterator * i );
121
+ int bson_iterator_int_raw( const bson_iterator * i );
122
+ int64_t bson_iterator_long_raw( const bson_iterator * i );
123
+ bson_bool_t bson_iterator_bool_raw( const bson_iterator * i );
124
+ bson_oid_t* bson_iterator_oid( const bson_iterator * i );
125
+
126
+ /* these can also be used with bson_code and bson_symbol*/
127
+ const char * bson_iterator_string( const bson_iterator * i );
128
+ int bson_iterator_string_len( const bson_iterator * i );
129
+
130
+ /* works with bson_code, bson_codewscope, and bson_string */
131
+ /* returns NULL for everything else */
132
+ const char * bson_iterator_code(const bson_iterator * i);
133
+
134
+ /* calls bson_empty on scope if not a bson_codewscope */
135
+ void bson_iterator_code_scope(const bson_iterator * i, bson * scope);
136
+
137
+ /* both of these only work with bson_date */
138
+ bson_date_t bson_iterator_date(const bson_iterator * i);
139
+ time_t bson_iterator_time_t(const bson_iterator * i);
140
+
141
+ int bson_iterator_bin_len( const bson_iterator * i );
142
+ char bson_iterator_bin_type( const bson_iterator * i );
143
+ const char * bson_iterator_bin_data( const bson_iterator * i );
144
+
145
+ const char * bson_iterator_regex( const bson_iterator * i );
146
+ const char * bson_iterator_regex_opts( const bson_iterator * i );
147
+
148
+ /* these work with bson_object and bson_array */
149
+ void bson_iterator_subobject(const bson_iterator * i, bson * sub);
150
+ void bson_iterator_subiterator(const bson_iterator * i, bson_iterator * sub);
151
+
152
+ /* str must be at least 24 hex chars + null byte */
153
+ void bson_oid_from_string(bson_oid_t* oid, const char* str);
154
+ void bson_oid_to_string(const bson_oid_t* oid, char* str);
155
+ void bson_oid_gen(bson_oid_t* oid);
156
+
157
+ time_t bson_oid_generated_time(bson_oid_t* oid); /* Gives the time the OID was created */
158
+
159
+ /* ----------------------------
160
+ BUILDING
161
+ ------------------------------ */
162
+
163
+ bson_buffer * bson_buffer_init( bson_buffer * b );
164
+ bson_buffer * bson_ensure_space( bson_buffer * b , const int bytesNeeded );
165
+
166
+ /**
167
+ * @return the raw data. you either should free this OR call bson_destroy not both
168
+ */
169
+ char * bson_buffer_finish( bson_buffer * b );
170
+ void bson_buffer_destroy( bson_buffer * b );
171
+
172
+ bson_buffer * bson_append_oid( bson_buffer * b , const char * name , const bson_oid_t* oid );
173
+ bson_buffer * bson_append_new_oid( bson_buffer * b , const char * name );
174
+ bson_buffer * bson_append_int( bson_buffer * b , const char * name , const int i );
175
+ bson_buffer * bson_append_long( bson_buffer * b , const char * name , const int64_t i );
176
+ bson_buffer * bson_append_double( bson_buffer * b , const char * name , const double d );
177
+ bson_buffer * bson_append_string( bson_buffer * b , const char * name , const char * str );
178
+ bson_buffer * bson_append_symbol( bson_buffer * b , const char * name , const char * str );
179
+ bson_buffer * bson_append_code( bson_buffer * b , const char * name , const char * str );
180
+ bson_buffer * bson_append_code_w_scope( bson_buffer * b , const char * name , const char * code , const bson * scope);
181
+ bson_buffer * bson_append_binary( bson_buffer * b, const char * name, char type, const char * str, int len );
182
+ bson_buffer * bson_append_bool( bson_buffer * b , const char * name , const bson_bool_t v );
183
+ bson_buffer * bson_append_null( bson_buffer * b , const char * name );
184
+ bson_buffer * bson_append_undefined( bson_buffer * b , const char * name );
185
+ bson_buffer * bson_append_regex( bson_buffer * b , const char * name , const char * pattern, const char * opts );
186
+ bson_buffer * bson_append_bson( bson_buffer * b , const char * name , const bson* bson);
187
+ bson_buffer * bson_append_element( bson_buffer * b, const char * name_or_null, const bson_iterator* elem);
188
+
189
+ /* these both append a bson_date */
190
+ bson_buffer * bson_append_date(bson_buffer * b, const char * name, bson_date_t millis);
191
+ bson_buffer * bson_append_time_t(bson_buffer * b, const char * name, time_t secs);
192
+
193
+ bson_buffer * bson_append_start_object( bson_buffer * b , const char * name );
194
+ bson_buffer * bson_append_start_array( bson_buffer * b , const char * name );
195
+ bson_buffer * bson_append_finish_object( bson_buffer * b );
196
+
197
+ void bson_numstr(char* str, int i);
198
+ void bson_incnumstr(char* str);
199
+
200
+
201
+ /* ------------------------------
202
+ ERROR HANDLING - also used in mongo code
203
+ ------------------------------ */
204
+
205
+ void * bson_malloc(int size); /* checks return value */
206
+
207
+ /* bson_err_handlers shouldn't return!!! */
208
+ typedef void(*bson_err_handler)(const char* errmsg);
209
+
210
+ /* returns old handler or NULL */
211
+ /* default handler prints error then exits with failure*/
212
+ bson_err_handler set_bson_err_handler(bson_err_handler func);
213
+
214
+
215
+
216
+ /* does nothing is ok != 0 */
217
+ void bson_fatal( int ok );
218
+ int bson_fatal_msg( int ok, const char* msg );
219
+
220
+ MONGO_EXTERN_C_END
221
+ #endif